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.