Потоки WebView никогда не останавливаются (WebViewCoreThread, CookieSyncManager, http [0-3]) - PullRequest
34 голосов
/ 11 января 2010

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

Ответы [ 10 ]

40 голосов
/ 20 августа 2010

Вы сможете остановить / возобновить эти потоки, вызвав 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

16 голосов
/ 26 сентября 2011

Мое решение, в расширенном классе веб-просмотра (протестировано в Android 2.2, Android 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) {}
     }
 }
13 голосов
/ 04 июня 2014

Чистое простое решение, которое делает работу:

@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 голосов
/ 14 марта 2011

Взгляните на эту ветку 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.

2 голосов
/ 17 мая 2013

А как насчет WebView.destroy ()? Это, кажется, убирает вещи или меня, не делая прикольных размышлений.

2 голосов
/ 13 октября 2011

Спасибо за эту информацию, у меня была проблема с приостановкой звука в моем 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);
}
1 голос
/ 31 мая 2014

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

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

Так я и работал. Может быть, это также полезно для вас.

0 голосов
/ 11 февраля 2015

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

    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");, чтобы возобновить.

0 голосов
/ 09 мая 2013

Вышеперечисленные решения для меня не сработали на Samsung Galaxy S с Android 2.3.3. Но я добился успеха, попробовав следующий обходной путь:

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

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

0 голосов
/ 21 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...