WebView-Methoden für denselben Threadfehler

84

Ich habe ein Android-Programm (Java + HTML in einer Webansicht). Ich kann vom Javascript zum Java-Code aufrufen. Aber umgekehrt hat es nicht mehr funktioniert (nach dem Update in Eclipse).

Das ist es also, was ich versuche zu tun

  • Erstellen Sie eine Webansicht (funktioniert)
  • Aufrufen von Javascript zu AndroidFunction.test (); (hat funktioniert)
  • der Java-Test test () ruft webView.loadUrl auf ("javascript: helloBack ()"); (! funktioniert nicht mehr)

Ich habe versucht, es mit dem WebView in der MainActivity arbeiten zu lassen, aber es hat nicht funktioniert.

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()");
    }

Error:

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)

Danke für die Antwort. Ich habe die Funktion in meiner Javascript-Datei folgendermaßen bearbeitet:

private void test(final String s) {
        webView.post(new Runnable() {
            public void run() {
                webView.loadUrl("javascript:" + s + ";");
            }
        });
        System.out.println("javscript done..");
    }
Johan Hoeksma
quelle
In Ihrer Bearbeitung erwähnen Sie, dass Sie Ihren Code basierend auf (einer) der Antwort (en) geändert haben, sodass es so klingt, als hätte dies Ihr Problem immer noch nicht gelöst - aber es gibt eine akzeptierte Antwort. Ich schlage vor, Sie machen deutlich, ob dies das Problem gelöst hat oder nicht (oder machen Sie die Bearbeitung auf andere Weise rückgängig).
Tom

Antworten:

211

Die JavaScript-Methode wird in einem Hintergrundthread (dh einem Nicht-UI-Thread) ausgeführt. Sie müssen alle Android View-bezogenen Methoden im UI-Thread aufrufen. Sie können erreichen, was Sie brauchen mit:

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

Dadurch wird die Aufgabe veröffentlicht, die auf dem UI-Thread ausgeführt werden soll.

ksasq
quelle
Wo haben Sie das Snippet (mWebView) zu Ihrem ursprünglichen Code hinzugefügt?
Bowie
In der Funktion test () siehe meine obige Frage.
Johan Hoeksma
Was ist, wenn Sie einen Wert zurückgeben müssen? zB webview.getUrl zurückgeben? stackoverflow.com/questions/29748782/… @JohanHoeksma
Suresh Subedi
Wissen Sie, wie und wann dieses Problem aufgetreten ist? In meinem Nexus 5X (Android 7.1.1) ist es in Ordnung, aber einige Geräte sind abgestürzt.
Ellie Zou
Wie übergebe ich eine Variable? Ich habe versucht, eine Variable in mWebView.loadUrl hinzuzufügen ("javascript: test ('" + MyData + "');"); aber der Wert wird nie an Javascript übergeben!
user1788736
14

In meinem Fall wurde in einer WebView nichts angezeigt, daher bevorzuge ich einen anderen Weg:

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

Dies kann mithilfe der Post-Methode behoben werden. Bitte gehen Sie den folgenden Code durch.

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

Java- Version: Sie müssen die Runnable- Schnittstelle und den Post to Handler verwenden .

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

Kotlin- Version:

webView.post(new Runnable {
   webView.loadUrl("file:///android_asset/www/index.html")
})
römisch
quelle