Metodi di WebView sullo stesso errore di thread


88

Ho un programma Android (Java + html in una visualizzazione web). Posso chiamare da javascript al codice Java. Ma il contrario ha smesso di funzionare (dopo l'aggiornamento in eclipse).

Quindi questo è quello che sto cercando di fare

  • Crea una visualizzazione web (funzionante)
  • chiamando in javascript ad AndroidFunction.test (); (lavorato)
  • la funzione java test () chiama webView.loadUrl ("javascript: helloBack ()"); (! non funziona più)

Ho provato a lasciarlo funzionare con WebView in MainActivity, ma non ha funzionato.

MainActivity.java

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final WebView webView = (WebView)findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebChromeClient(new WebChromeClient());
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        javascr = new Javascript(this, webView);
        webView.addJavascriptInterface(javascr, "AndroidFunction");
        webView.loadUrl("file:///android_asset/www/index.html");

        ....
}

Javascript.java

public class Javascript {   
    Context cont;
    WebView webView;

    Javascript(Context c, WebView w) {
        cont = c;
        webView = w;
    }

    // function called in the javascript by AndroidFunction.test();
    public void test() {
          // Breaking point!!!
        webView.loadUrl("javascript:helloBack()");
    }

Errore:

03-24 11:47:50.103: W/WebView(21026):   at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
03-24 11:47:50.103: W/WebView(21026):   java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper{41ab68f8} called on Looper{41bb70a8}, FYI main Looper is Looper{41ab68f8})

03-24 11:47:50.103: W/WebView(21026):   at android.webkit.WebView.checkThread(WebView.java:2063)
03-24 11:47:50.103: W/WebView(21026):   at android.webkit.WebView.loadUrl(WebView.java:794)
03-24 11:47:50.103: W/WebView(21026):   at com.example.hellobt.Javascript.test(Javascript.java:24)

03-24 11:47:50.103: W/WebView(21026):   at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
03-24 11:47:50.103: W/WebView(21026):   at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
03-24 11:47:50.103: W/WebView(21026):   at android.os.Handler.dispatchMessage(Handler.java:102)

03-24 11:47:50.103: W/WebView(21026):   at android.os.Looper.loop(Looper.java:137)
03-24 11:47:50.103: W/WebView(21026):   at android.os.HandlerThread.run(HandlerThread.java:61)

Grazie per la risposta. Ho modificato la funzione nel mio file Javascript in questo modo:

private void test(final String s) {
        webView.post(new Runnable() {
            public void run() {
                webView.loadUrl("javascript:" + s + ";");
            }
        });
        System.out.println("javscript done..");
    }

Nella tua modifica menzioni che hai cambiato il tuo codice in base a (una delle) risposte, facendo sembrare che questo non abbia ancora risolto il tuo problema, ma c'è una risposta accettata. Ti suggerisco di rendere esplicito se questo ha risolto il problema o meno (o altrimenti basta annullare la modifica).
— Tom

Risposte:


214

Il metodo JavaScript viene eseguito su un thread in background (cioè non UI). È necessario chiamare tutti i metodi correlati alla visualizzazione di Android nel thread dell'interfaccia utente. Puoi ottenere ciò di cui hai bisogno con:

mWebView.post(new Runnable() {
    @Override
    public void run() {
        mWebView.loadUrl(...).
    }
});

Che pubblicherà l'attività da eseguire sul thread dell'interfaccia utente.


dove hai aggiunto lo snippet (mWebView) al tuo codice originale?
— Bowie

Nella funzione test (), vedere la mia domanda precedente.
— Johan Hoeksma

Cosa succede se devi restituire un valore? es. return webview.getUrl? stackoverflow.com/questions/29748782/... @JohanHoeksma
— Suresh Subedi

Sai come e quando si è verificato questo problema? Nel mio Nexus 5X (Android 7.1.1), va bene, ma alcuni dispositivi si sono bloccati.
— Ellie Zou

come passare una variabile? Ho provato ad aggiungere una variabile in mWebView.loadUrl ("javascript: test ('" + MyData + "');"); ma il valore non viene mai passato a javascript!
— user1788736

15

Nel mio caso non è stato mostrato nulla in una WebView, quindi preferisco un altro modo:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        final WebView webView = (WebView) findViewById(R.id.map);
        webView.loadDataWithBaseURL(...);
    }
});

3

Questo può essere ottenuto utilizzando il metodo post. Si prega di passare attraverso il codice sottostante.

 m_targetView.post(new Runnable() {
                        @Override
                        public void run() {
                            m_targetView.loadUrl(".....");
                        }
                    });

3

Versione Java : è necessario utilizzare l' interfaccia Runnable e Post to Handler .

webView.post(new Runnable() {
          @Override
          public void run() {
             webView.loadUrl("file:///android_asset/www/index.html");
          }
       });

Versione Kotlin :

webView.post(new Runnable {
   webView.loadUrl("file:///android_asset/www/index.html")
})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.