Métodos WebView en el mismo error de hilo


84

Tengo un programa de Android (Java + html en una vista web). Puedo llamar desde javascript al código Java. Pero al revés dejó de funcionar (después de actualizar en eclipse).

Entonces esto es lo que estoy tratando de hacer

  • Hacer una vista web (funcionado)
  • llamando en javascript a AndroidFunction.test (); (trabajó)
  • la función java test () llamada webView.loadUrl ("javascript: helloBack ()"); (! ya no funciona)

Intenté dejar que funcionara con WebView en MainActivity, pero no funcionó.

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)

Gracias por la respuesta. Edité la función en mi archivo Javascript así:

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

En su edición, menciona que ha cambiado su código en función de (una de) las respuestas, lo que hace que parezca que esto aún no ha resuelto su problema, pero hay una respuesta aceptada. Le sugiero que deje explícito si esto resolvió el problema o no (o simplemente deshaga la edición).
Tom

Respuestas:


212

El método de JavaScript se ejecuta en un hilo de fondo (es decir, no UI). Debe llamar a todos los métodos relacionados con Android View en el hilo de la interfaz de usuario. Puede lograr lo que necesita con:

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

Que publicará la tarea para que se ejecute en el hilo de la IU.


¿Dónde agregaste el fragmento (mWebView) a tu código original?
Bowie

En la función test (), vea mi pregunta anterior.
Johan Hoeksma

¿Qué sucede si necesita devolver un valor? por ejemplo, return webview.getUrl? stackoverflow.com/questions/29748782/… @JohanHoeksma
Suresh Subedi

¿Sabes cómo y cuándo ocurrió este problema? En mi Nexus 5X (Android 7.1.1), está bien, pero algunos dispositivos fallaron.
Ellie Zou

¿Cómo pasar una variable? Intenté agregar una variable en mWebView.loadUrl ("javascript: test ('" + MyData + "');"); ¡pero el valor nunca se pasa a javascript!
user1788736

14

En mi caso, no se mostró nada en WebView, así que prefiero otra forma:

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

3

Esto se puede solucionar mediante el método de publicación. Por favor revise el siguiente código.

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

2

Versión de Java : debe utilizar la interfaz Runnable y Post to Handler .

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

Versión de Kotlin :

webView.post(new Runnable {
   webView.loadUrl("file:///android_asset/www/index.html")
})
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.