android webview.loadUrl won't load another webpage

12,283

As mentioned by ProfessorT, there are many threads running behind the scenes with the WebView, and callbacks from JavaScript via JavaScript interface objects are made on a background thread.

You can achieve what you like with some code like this inside loadNextTest:

myWebView.post(new Runnable() {
    @Override
    public void run() {
        webviewLoadURL("file:///android_asset/test1.html");
    }
});

Please also note that your state variable will also be written on the JavaScript background thread so you many need to synchronize your read/writes if they are coming from other threads too.

Share:
12,283
Admin
Author by

Admin

Updated on June 05, 2022

Comments

  • Admin
    Admin almost 2 years

    In my simple android app I programmatically load a webpage in the WebView. It initially starts with a default webpage, and the next one is loaded based upon the user inputs for the first one. The JavaScript pass information back into the Android side of things via a message. Everything works fine, except when the second webpage doesn't load no matter what I do and which URL I give. When I load the second test, a warning appears "All WebView methods must be called on the same thread." But to my knowledge I'm not using multithreading, nor do I need to use multithreading.

    Here's the relevant code:

    public class MainActivity extends Activity {
        public WebView myWebView;
        public int state;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
    
            setContentView(R.layout.activity_main);
    
            myWebView = (WebView) findViewById(R.id.webview);
    
            WebSettings myWebViewSettings = myWebView.getSettings();
            myWebViewSettings.setJavaScriptEnabled(true);
            myWebViewSettings.setDomStorageEnabled(true);
            myWebViewSettings.setAllowFileAccessFromFileURLs(true);
            myWebViewSettings.setAllowUniversalAccessFromFileURLs(true);
    
            myWebView.addJavascriptInterface(new JavascriptHandler(), "cpjs");
    
            state = 0;
            loadNextTest();
        }
    
        public void webviewLoadURL(String url) {
            Log.d("app", "now loading " + url);
            myWebView.clearHistory();
            myWebView.clearFormData();
            myWebView.clearCache(true);
            myWebView.loadUrl(url);
        }
    
        final class JavascriptHandler {
               @JavascriptInterface
               public void sendToAndroid(String text) {
                    if (text.equals("confirmed at target")) {
                        loadNextTest();
                    }
               }
        }
    
        public void loadNextTest() {
            Log.d("app", "now loading test " + (state + 1));
            if (state == 0) {
                webviewLoadURL("file:///android_asset/test1.html");
                state = state + 1;
    
            } else if (state == 1) {
                webviewLoadURL("file:///android_asset/test2.html");
                // webviewLoadURL("http://www.google.com");
                state = state + 1;
    
            } else {
                webviewLoadURL("file:///android_asset/test3.html");
            }
        }
    }
    

    Here's the relevant log lines:

    02-22 09:12:32.250: V/WebViewChromium(15117): Binding Chromium to the background looper Looper (main, tid 1) {41c7ec00}
    02-22 09:12:32.250: I/chromium(15117): [INFO:library_loader_hooks.cc(112)] Chromium logging enabled: level = 0, default verbosity = 0
    02-22 09:12:32.255: I/BrowserProcessMain(15117): Initializing chromium process, renderers=0
    02-22 09:12:32.265: W/chromium(15117): [WARNING:proxy_service.cc(888)] PAC support disabled because there is no system implementation
    02-22 09:12:32.315: D/dalvikvm(15117): GC_FOR_ALLOC freed 86K, 5% free 3217K/3364K, paused 8ms, total 8ms
    02-22 09:12:32.315: I/dalvikvm-heap(15117): Grow heap (frag case) to 4.273MB for 1127536-byte allocation
    02-22 09:12:32.325: D/dalvikvm(15117): GC_FOR_ALLOC freed <1K, 4% free 4318K/4468K, paused 11ms, total 11ms
    02-22 09:12:32.345: D/dalvikvm(15117): GC_CONCURRENT freed <1K, 4% free 4317K/4468K, paused 1ms+6ms, total 17ms
    02-22 09:12:32.365: D/app(15117): now loading test 1
    02-22 09:12:32.365: D/app(15117): now loading file:///android_asset/test1.html
    02-22 09:12:32.450: D/mali_winsys(15117): new_window_surface returns 0x3000
    02-22 09:12:32.460: I/Icing(794): Indexing 5AA949AFB589F1D17D8668589402D01E615E228D from com.google.android.googlequicksearchbox
    02-22 09:12:32.500: D/OpenGLRenderer(15117): Enabling debug mode 0
    02-22 09:12:32.505: W/AwContents(15117): nativeOnDraw failed; clearing to background color.
    02-22 09:12:32.540: I/ActivityManager(447): Displayed com.example.myApp/.MainActivity: +344ms
    02-22 09:12:32.550: W/AwContents(15117): nativeOnDraw failed; clearing to background color.
    02-22 09:12:32.635: I/Icing(794): Indexing done 5AA949AFB589F1D17D8668589402D01E615E228D
    02-22 09:12:32.945: I/chromium(15117): [INFO:async_pixel_transfer_manager_android.cc(56)] Async pixel transfers not supported
    02-22 09:12:32.960: I/chromium(15117): [INFO:async_pixel_transfer_manager_android.cc(56)] Async pixel transfers not supported
    02-22 09:12:33.180: E/AndroidProtocolHandler(15117): Unable to open asset URL: file:///android_asset/backend/images/ajax-loader.gif
    02-22 09:12:46.010: D/app(15117): now loading test 2
    02-22 09:12:46.010: D/app(15117): now loading http://www.google.com
    02-22 09:12:46.020: W/WebView(15117): java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {41c7ec00} called on Looper (JavaBridge, tid 271) {41c6f5c8}, FYI main Looper is Looper (main, tid 1) {41c7ec00})
    02-22 09:12:46.020: W/WebView(15117):   at android.webkit.WebView.checkThread(WebView.java:2063)
    02-22 09:12:46.020: W/WebView(15117):   at android.webkit.WebView.clearHistory(WebView.java:1399)
    02-22 09:12:46.020: W/WebView(15117):   at com.example.myApp.MainActivity.webviewLoadURL(MainActivity.java:68)
    02-22 09:12:46.020: W/WebView(15117):   at com.example.myApp.MainActivity.loadNextTest(MainActivity.java:91)
    02-22 09:12:46.020: W/WebView(15117):   at com.example.myApp.MainActivity$JavascriptHandler.sendToAndroid(MainActivity.java:78)
    02-22 09:12:46.020: W/WebView(15117):   at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
    02-22 09:12:46.020: W/WebView(15117):   at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
    02-22 09:12:46.020: W/WebView(15117):   at android.os.Handler.dispatchMessage(Handler.java:102)
    02-22 09:12:46.020: W/WebView(15117):   at android.os.Looper.loop(Looper.java:136)
    02-22 09:12:46.020: W/WebView(15117):   at android.os.HandlerThread.run(HandlerThread.java:61)
    02-22 09:12:46.030: W/System.err(15117): java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {41c7ec00} called on Looper (JavaBridge, tid 271) {41c6f5c8}, FYI main Looper is Looper (main, tid 1) {41c7ec00})
    02-22 09:12:46.035: W/System.err(15117):    at android.webkit.WebView.checkThread(WebView.java:2073)
    02-22 09:12:46.035: W/System.err(15117):    at android.webkit.WebView.clearHistory(WebView.java:1399)
    02-22 09:12:46.035: W/System.err(15117):    at com.example.myApp.MainActivity.webviewLoadURL(MainActivity.java:68)
    02-22 09:12:46.035: W/System.err(15117):    at com.example.myApp.MainActivity.loadNextTest(MainActivity.java:91)
    02-22 09:12:46.035: W/System.err(15117):    at com.example.myApp.MainActivity$JavascriptHandler.sendToAndroid(MainActivity.java:78)
    02-22 09:12:46.035: W/System.err(15117):    at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
    02-22 09:12:46.040: W/System.err(15117):    at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
    02-22 09:12:46.040: W/System.err(15117):    at android.os.Handler.dispatchMessage(Handler.java:102)
    02-22 09:12:46.040: W/System.err(15117):    at android.os.Looper.loop(Looper.java:136)
    02-22 09:12:46.040: W/System.err(15117):    at android.os.HandlerThread.run(HandlerThread.java:61)
    02-22 09:12:46.040: W/System.err(15117): Caused by: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {41c7ec00} called on Looper (JavaBridge, tid 271) {41c6f5c8}, FYI main Looper is Looper (main, tid 1) {41c7ec00})
    02-22 09:12:46.045: W/System.err(15117):    at android.webkit.WebView.checkThread(WebView.java:2063)
    02-22 09:12:46.045: W/System.err(15117):    ... 9 more
    

    Any help is appreciated. Thanks.