我使用WebView在我们的某个应用程序上显示一些互联网内容
活动。
问题是当用户退出此活动时,
WebView的线程继续运行!
有问题的线程是:
Thread [<17> WebViewCoreThread] (Running)
Thread [<25> CookieSyncManager] (Running)
Thread [<19> http0] (Running)
Thread [<29> http1] (Running)
Thread [<31> http2] (Running)
Thread [<33> http3] (Running)
暂停这些线程中的每一个,并检查它正忙着做什么:
Thread [<17> WebViewCoreThread] (Suspended)
Object.wait(long, int) line: not available [native method]
MessageQueue(Object).wait() line: 288
MessageQueue.next() line: 148
Looper.loop() line: 110
WebViewCore$WebCoreThread.run() line: 471
Thread.run() line: 1060
Thread [<25> CookieSyncManager] (Suspended)
Object.wait(long, int) line: not available [native method]
MessageQueue(Object).wait(long) line: 326
MessageQueue.next() line: 144
Looper.loop() line: 110
CookieSyncManager(WebSyncManager).run() line: 90
Thread.run() line: 1060
Thread [<19> http0] (Suspended)
Object.wait(long, int) line: not available [native method]
RequestQueue(Object).wait() line: 288
ConnectionThread.run() line: 93
我想知道如何告诉每个线程中的Looper
退出。
我尝试在活动的webView.destroy()
方法中调用onPause()
,
但它没有影响力
当我禁用在webView中打开网页的调用时
(webView.loadUrl(...)
),这些线程自然没有启动,并且
所以在离开活动后不要继续留下。
关于如何让WebView
的线程在离开后停止的任何想法
他们的活动?
答案 0 :(得分:40)
您应该可以通过调用webview上的onPause / onResume来停止/恢复这些线程。
然而,这些是隐藏的,所以你需要通过反思来做到这一点。以下代码对我有用:
Class.forName("android.webkit.WebView").getMethod("onPause", (Class[]) null).invoke(webView, (Object[]) null);
其中webView是WebView的实例。
答案 1 :(得分:16)
我的解决方案,在扩展的webview类中(在android 2.2中测试,andriod 2.3,android 3.1):
private boolean is_gone = false;
public void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if (visibility == View.GONE) {
try {
WebView.class.getMethod("onPause").invoke(this); //stop flash
} catch (Exception e) {}
this.pauseTimers();
this.is_gone = true;
} else if (visibility == View.VISIBLE) {
try {
WebView.class.getMethod("onResume").invoke(this); //resume flash
} catch (Exception e) {}
this.resumeTimers();
this.is_gone = false;
}
}
public void onDetachedFromWindow() { //this will be trigger when back key pressed, not when home key pressed
if (this.is_gone) {
try {
this.destroy();
} catch (Exception e) {}
}
}
答案 2 :(得分:13)
干净简单的解决方案:
@Override
public void onPause() {
super.onPause();
webView.onPause();
webView.pauseTimers(); //careful with this! Pauses all layout, parsing, and JavaScript timers for all WebViews.
}
@Override
public void onResume() {
super.onResume();
webView.onResume();
webView.resumeTimers();
}
@Override
public void onDestroy() {
super.onDestroy();
parentViewGroup.removeAllViews(); //the viewgroup the webview is attached to
webView.loadUrl("about:blank");
webView.stopLoading();
webView.setWebChromeClient(null);
webView.setWebViewClient(null);
webView.destroy();
webView = null;
}
答案 3 :(得分:4)
看看这个andev.org帖子(WebViewCoreThread problem)。
查看回复... Re: WebViewCoreThread problem - Postby potatoho
2)要暂停flash,你必须调用隐藏方法WebView.onPause()/ WebView.onResume()。
3)要暂停WebViewCoreThread,请使用WebView.pauseTimers()/ WebView.resumeTimers()。
我跳过了onPause / onResume,但我实现了webView.pauseTimers()
和webView.resumeTimers()
,它至少可以阻止CPU出血。
我还在我的onPause / onResume上添加了CookieSyncManager.getInstance().stopSync()
/ startSync
。
答案 4 :(得分:2)
感谢您提供这些信息,当我按下手机上的锁定按钮时,我遇到了这个问题在我的swf上停止声音,当我按下解锁按钮但是活动仍然不可见时,onPause和onResume仍然播放我的瑞士法郎如果你想在webView中暂停和恢复播放swf声音,我建议你将它们放在onWindowFocusChanged上
@Override
public void onWindowFocusChanged(boolean hasFocus) {
gameView = (WebView) findViewById(R.id.gameView);
// TODO Auto-generated method stub
if (hasFocus) {
try {
Class.forName("android.webkit.WebView")
.getMethod("onResume", (Class[]) null)
.invoke(gameView, (Object[]) null);
} catch (Exception e) {
}
gameView.resumeTimers();
gameView.loadUrl("javascript:setflashfocus()");
} else {
try {
Class.forName("android.webkit.WebView")
.getMethod("onPause", (Class[]) null)
.invoke(gameView, (Object[]) null);
} catch (Exception e) {
}
gameView.pauseTimers();
}
super.onWindowFocusChanged(hasFocus);
}
答案 5 :(得分:2)
WebView.destroy()怎么样?这似乎是在清理事物或者我没有做任何时髦的反射调用。
答案 6 :(得分:1)
实际上,使用webView.destroy(), onPause(), clear**()
无法阻止Webcore及其相关的线程。
实际上,理想的方法是将WebView所在的活动设置为一个独立的进程,这样当活动结束时,包括Webcore在内的所有线程都将被销毁。
这就是我的工作方式。也许它对你也有用。
答案 7 :(得分:0)
我不得不调用WebView的onDestroy来专门为webview清除内存。当我们用webview回到这个活动时,我正在加载flash并且它正在杀死我的应用程序。如果你每次使用它都不会破坏你的WebView,那么Flash会让你活着。
答案 8 :(得分:0)
以上的解决方案在三星Galaxy S和Android 2.3.3上都失败了。 但是我尝试了下面的解决方法取得了成功:
webview.loadUrl("file:///android_asset/nonexistent.html");
我正在强制webview加载一个不存在的html文件。这似乎迫使webview清理了一切。
答案 9 :(得分:0)
定义方法:
private void hiddenWebViewMethod(String state){
if( webView != null ){
try {
Method method = WebView.class.getMethod(state);
method.invoke(webView);
} catch (Exception e) {
Log.e("TAG", "Exception: " + e.toString());
webView.loadData("", "text/html", "utf-8");
}
}
}
然后致电hiddenWebViewMethod("onPause");
停止加载,hiddenWebViewMethod("onResume");
恢复。