Android WebView 线程永不停止(WebViewCoreThread、CookieSyncManager、http[0-3])

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2040963/
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-20 04:18:53  来源:igfitidea点击:

WebView threads never stop (WebViewCoreThread, CookieSyncManager, http[0-3])

androidmultithreadingwebview

提问by Amit Kotlovski

I use a WebView to display some internet content on one of our app's Activities.
The problem is that when the user switches out of this activity, WebView's threads keep running!
The problematic threads are:

我使用 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)

Pausing each one of these threads, and checking what it is busy doing:

暂停这些线程中的每一个,并检查它正在忙于做什么:

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

I wonder how can I tell the Looperin each of those threads to quit.

我想知道如何告诉Looper每个线程中的退出。

I tried calling webView.destroy()in the activity's onPause()method, but it had no influence.
When I disable the call for opening a web page in the webView ( webView.loadUrl(...)), those threads naturally are not started, and therefore don't stay on after leaving the activity.

我尝试调用webView.destroy()活动的onPause()方法,但它没有影响。
当我在 webView ( webView.loadUrl(...)) 中禁用打开网页的调用时,这些线程自然不会启动,因此在离开活动后不会继续存在。

Any ideas as to how I can make WebView's threads stop after leaving their activity?

关于如何让WebView的线程在离开他们的活动后停止的任何想法?

回答by Skymt

You should be able to stop / resume these threads by calling the onPause / onResume on the webview.

您应该能够通过在 webview 上调用 onPause / onResume 来停止/恢复这些线程。

Those are however hidden, so you will need to do it through reflection. The following code worked for me:

然而,这些是隐藏的,所以你需要通过反思来做到这一点。以下代码对我有用:

Class.forName("android.webkit.WebView").getMethod("onPause", (Class[]) null).invoke(webView, (Object[]) null);

Where webView is the instance of WebView.

其中 webView 是 WebView 的实例。

Also see: http://code.google.com/p/android/issues/detail?id=10282

另请参阅:http: //code.google.com/p/android/issues/detail?id=10282

回答by diyism

My solution, in extended webview class(tested in android 2.2, andriod 2.3, android 3.1):

我的解决方案,在扩展的 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) {}
     }
 }

回答by Bolling

A clean easy solution that does the job:

一个干净简单的解决方案,可以完成这项工作:

@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;
}

回答by rquinn

Take a look at this andev.org thread (WebViewCoreThread problem).

看看这个 andev.org 线程(WebViewCoreThread 问题)。

See the response... Re: WebViewCoreThread problem - Postby potatoho

看到响应... Re: WebViewCoreThread 问题 - Postby土豆

2) To pause flash you have to call hidden methods WebView.onPause() / WebView.onResume().

3) To pause WebViewCoreThread you use WebView.pauseTimers() / WebView.resumeTimers().

2) 要暂停 Flash,您必须调用隐藏方法 WebView.onPause() / WebView.onResume()。

3) 要暂停 WebViewCoreThread,您可以使用 WebView.pauseTimers() / WebView.resumeTimers()。

I skipped the onPause/onResume, but I implemented webView.pauseTimers()and webView.resumeTimers()and it at least stops the CPU bleed.

我跳过了在onPause /的onResume,但我实现了webView.pauseTimers()webView.resumeTimers()它至少停止CPU出血。

I also added CookieSyncManager.getInstance().stopSync()/ startSyncto my onPause/onResume as well.

我还将CookieSyncManager.getInstance().stopSync()/添加startSync到我的 onPause/onResume 中。

回答by Keiichi

Thanks for these info, I had this problem pausing sounds in my swf on webView when I press the lock button on the phone, onPause and onResume still plays my swf when i press the unlock button but the activity is still not visible, I suggest you place these on onWindowFocusChanged if you want to pause and resume playing of swf sounds in webView

感谢您提供这些信息,当我按下手机上的锁定按钮时,我在 webView 上的 swf 中遇到了暂停声音的问题,当我按下解锁按钮时,onPause 和 onResume 仍然播放我的 swf,但活动仍然不可见,我建议您如果您想在 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);
}

回答by Dan Carpenter

What about WebView.destroy()? That seems to be cleaning things up or me without doing any funky reflection calls.

WebView.destroy() 怎么样?这似乎是在清理事情或我,而无需进行任何时髦的反射调用。

回答by Verdigrass

Actually, using webView.destroy(), onPause(), clear**()cannot stop Webcore and its related threads yet.

实际上,使用webView.destroy(), onPause(), clear**()还不能停止 Webcore 及其相关线程。

Practically, an ideal way is to set the activity where WebView resides to be in an independent process, so that when the activity is finished, all the threads including Webcore will be destroyed.

实际上,一种理想的方式是将WebView所在的Activity设置在一个独立的进程中,这样当Activity结束时,包括Webcore在内的所有线程都会被销毁。

That is the way I have employed. Maybe it is also useful to you.

这就是我就业的方式。也许它对你也有用。

回答by dangel

The above solutions failed for me on Samsung Galaxy S with Android 2.3.3. But I made success trying the below workaround:

在使用 Android 2.3.3 的三星 Galaxy S 上,上述解决方案对我来说失败了。但我尝试以下解决方法取得了成功:

    webview.loadUrl("file:///android_asset/nonexistent.html");

I am forcing the webview to load a non existent html file. This seems to be forcing the webview to clean things up.

我正在强制 webview 加载一个不存在的 html 文件。这似乎迫使 webview 进行清理。

回答by Eric Novins

I had to call onDestroy of the WebView to clear the memory specifically for the webview. I was loading flash in and it was killing my app when we go back to this activity with a webview. Flash will eat you alive if you don't destroy your WebView EVERY TIME you're done with it.

我不得不调用 WebView 的 onDestroy 来专门为 webview 清除内存。我正在加载 flash,当我们使用 webview 返回此活动时,它正在杀死我的应用程序。如果您每次使用完 WebView 都不销毁 Flash,Flash 会活活吃掉您。

回答by Ayaz Alifov

Define a method:

定义一个方法:

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

then call hiddenWebViewMethod("onPause");to stop loading, and hiddenWebViewMethod("onResume");to resume.

然后调用hiddenWebViewMethod("onPause");停止加载,并 hiddenWebViewMethod("onResume");恢复。