Java android webview.loadUrl 不会加载另一个网页

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21955593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:37:40  来源:igfitidea点击:

android webview.loadUrl won't load another webpage

javajavascriptandroidwebviewandroid-webview

提问by yansun0

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.

在我的简单 android 应用程序中,我以编程方式在 WebView 中加载一个网页。它最初从一个默认网页开始,然后根据用户对第一个网页的输入加载下一个网页。JavaScript 通过消息将信息传递回 Android 端。一切正常,除非无论我做什么以及我提供哪个 URL,第二个网页都无法加载。当我加载第二个测试时,出现警告“必须在同一线程上调用所有 WebView 方法”。但据我所知,我没有使用多线程,也不需要使用多线程。

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.

任何帮助表示赞赏。谢谢。

采纳答案by ksasq

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.

正如ProfessorT 所提到的,WebView 在后台运行着许多线程,并且通过JavaScript 接口对象从JavaScript 回调是在后台线程上进行的。

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

你可以用一些像这样的代码来实现你喜欢的loadNextTest

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

Please also note that your statevariable 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.

另请注意,您的state变量也将写入 JavaScript 后台线程,因此如果它们也来自其他线程,则您需要同步您的读/写。

回答by ProfessorT

The object that is bound to your JavaScript runs in another thread and not in the thread in which it was constructed.

绑定到 JavaScript 的对象在另一个线程中运行,而不是在构造它的线程中运行。

You can force all your webview url loading to be done on the main thread, check this out:

您可以强制在主线程上完成所有 webview url 加载,请查看:

Run Callback On Main Thread

在主线程上运行回调