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