2014-02-22 79 views
8

在我簡單的android應用程序中,我以編程方式在WebView中加載網頁。它最初是從一個默認網頁開始的,而下一個是根據第一個用戶的輸入加載的。 JavaScript通過消息將信息傳回Android的一面。一切工作正常,除非第二個網頁不加載,不管我做了什麼,我給了哪個URL。當我加載第二個測試時,會出現一個警告:「所有WebView方法必須在同一個線程上調用。」但據我所知,我不使用多線程,也不需要使用多線程。android webview.loadUrl將不會加載其他網頁

下面是相關代碼:

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 

任何幫助表示讚賞。謝謝。

回答

18

正如ProfessorT提到的,有運行具有的WebView幕後許多線程,並且通過JavaScript接口對象從JavaScript進行回調是在後臺線程上進行的。

你可以實現你裏面loadNextTest像這樣的代碼,如:

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

也請注意,您state變量也會對JavaScript的後臺線程寫入,所以你許多需要你讀的同步/如果它們也來自其他線程,則寫入。

+0

謝謝,這工作就像一個魅力。 – yansun0

0

綁定到您的JavaScript的對象在另一個線程中運行,而不在其構建的線程中運行。

可以強制所有的WebView網址加載要在主線程上完成,檢查了這一點:

Run Callback On Main Thread

相關問題