【问题标题】:android webview.loadUrl won't load another webpageandroid webview.loadUrl 不会加载另一个网页
【发布时间】:2014-03-24 05:12:12
【问题描述】:

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

以下是相关代码:

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

以下是相关的日志行:

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

感谢任何帮助。谢谢。

【问题讨论】:

    标签: java javascript android webview android-webview


    【解决方案1】:

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

    您可以在loadNextTest 中使用类似这样的代码:

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

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

    【讨论】:

      【解决方案2】:

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

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

      Run Callback On Main Thread

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-26
        • 1970-01-01
        • 2013-08-22
        • 1970-01-01
        • 2011-12-17
        • 1970-01-01
        相关资源
        最近更新 更多