2013-12-19 9 views
3

如果執行的JavaScript代碼被無限循環捕獲,則Android WebView小部件顯示爲進入不可恢復狀態。如果執行JavaScript進入無限循環,Android WebView將進入不可恢復狀態

例如,該網頁將導致問題:

<html> 
<head> 
<title>FAIL</title> 
<script type="text/javascript"> 
    function test() { 
     while (true); 
    } 
</script> 
</head> 
<body onload="test();"> 
Failure Test 
</body> 

如將簡單地使用web視圖輸入以下URL在任何Android瀏覽器:

javascript:while(true); 

一旦這樣的無限會遇到一個循環,一個CPU內核將運行最大值。 WebView似乎從不關閉。這當然會迅速消耗電池並減慢設備速度。只有終止包含應用程序才能解決此問題。

下面似乎是無效的:

  • 禁用JavaScript的:webView.getSettings()setJavaScriptEnabled(假)。
  • 停止加載頁面:webView.stopLoading();暫停所有JS定時器:webView.pauseTimers();
  • 加載替代網址:webView.loadUrl(「about:blank」);
  • 從窗口小部件層次結構中刪除WebView:parent.removeView(browserView);
  • 在WebView上調用destroy:webView.destroy();
  • 完成活動:activity.finish();
  • 從WebChromeClient.onJsTimeout()返回false; (此方法在API 17中已棄用,並且似乎永遠不會被調用)。

以下是有效的:

  • 殺害該VM:System.exit(0); (這是一種絕不應該在Android上調用的方法。)

值得注意的是,股票Android瀏覽器(而非Chrome)也遭遇了這個問題。雖然Chrome不存在這個問題,但在使用Android 4.4中提供的基於Chromium的WebView時,它仍然會出現。

一旦一個WebView進入此狀態,應用程序將無法將任何URL加載到任何其他WebView中。

如果任何人有任何關於終止WebView的建議,將不勝感激。我無法控制加載到WebView中的內容,因爲它被用於通用瀏覽器。否則,我的默認解決方案將嘗試檢測方案並在用戶遇到問題時發出警告,並提供強制終止應用程序以防止電池耗盡的選項。

謝謝你的任何想法!

回答

1

我不認爲你可以做太多的事情。因爲WebView是單一進程(對於4.4 WebView也是如此),並且渲染程序正在應用程序的進程中運行,所以運行異常的Web頁面可能導致您的進程被分配大量內存而導致OOM死亡。

Chrome不會遇到這個問題,因爲它在可以被殺死的單獨進程中運行渲染器。 WebView可以被修改以殺死JavaScript執行正在發生的線程,但是這會導致內存泄漏(因爲操作系統不會像在單獨的進程中那樣爲您清理),就像我上面所說的那樣 - 這樣做並不能真正保護您免於分配內存的惡意網頁。

我認爲你的解決方案顯示「該頁面沒有響應。殺死應用程序?」向用戶彈出是使用WebView可以做的最好的選擇。另一種方法是基於Chromium代碼創建自己的多進程瀏覽器,但這可能需要花費更多的精力。