Темы WebView никогда не останавливаются (WebViewCoreThread, CookieSyncManager, http [0-3])

Я использую 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 прекратить после ухода их деятельность?

Ответ 1

Вы должны иметь возможность останавливать/возобновлять эти потоки, вызывая onPause/onResume на веб-просмотре.

Тем не менее они скрыты, поэтому вам нужно будет сделать это через отражение. Следующий код работал у меня:

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

Где webView является экземпляром WebView.

Также см.: http://code.google.com/p/android/issues/detail?id=10282

Ответ 2

Мое решение в расширенном классе 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) {}
     }
 }

Ответ 3

Чистое простое решение, выполняющее задание:

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

Ответ 4

Взгляните на эту ветку andev.org(проблема WebViewCoreThread).

См. ответ... Re: Проблема WebViewCoreThread - Postby potatoho

2) Чтобы приостановить флэш-память, вы должны вызвать скрытые методы WebView.onPause()/WebView.onResume().

3) Чтобы приостановить WebViewCoreThread, вы используете WebView.pauseTimers()/WebView.resumeTimers().

Я пропустил onPause/onResume, но я реализовал webView.pauseTimers() и webView.resumeTimers(), и он по крайней мере останавливает кровотечение процессора.

Я также добавил CookieSyncManager.getInstance().stopSync()/startSync в мой onPause/onResume.

Ответ 5

Спасибо за эту информацию, у меня была проблема с паузой в моем swf на webView, когда я нажимаю кнопку блокировки на телефоне, onPause и onResume все еще играет мой swf, когда я нажимаю кнопку разблокировки, но активность все еще не видна, Я предлагаю вам поместить их в onWindowFocusChanged, если вы хотите приостановить и возобновить воспроизведение звуков swf в webView

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

Ответ 6

Как насчет WebView.destroy()? Кажется, что это чистка вещей или меня, без каких-либо причудливых рефлекторных звонков.

Ответ 7

Мне пришлось вызвать onDestroy из WebView, чтобы очистить память специально для веб-просмотра. Я загружал флеш-память, и это убивало мое приложение, когда мы возвращаемся к этому действию с помощью веб-просмотра. Flash съест вас в живых, если вы не уничтожаете свой WebView КАЖДОЕ ВРЕМЯ, с которым вы закончили.

Ответ 8

Вышеупомянутые решения не удались для меня на Samsung Galaxy S с Android 2.3.3. Но я сделал успешную попытку обходного пути ниже:

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

Я заставляю webview загружать несуществующий html файл. Кажется, это заставляет веб-просмотр очищать вещи.

Ответ 9

На самом деле использование webView.destroy(), onPause(), clear**() еще не может остановить веб-контент и связанные с ним потоки.

Практически идеальным способом является настройка активности, в которой WebView находится в независимом процессе, поэтому, когда действие будет завершено, все потоки, включая Webcore, будут уничтожены.

Вот как я работал. Возможно, это также полезно для вас.

Ответ 10

Определите метод:

    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"); для возобновления.