J'utilise une WebView pour afficher du contenu Internet sur l'une de nos activités De notre application.
Le problème, c’est que lorsque l’utilisateur quitte cette activité, les threads de WebView continuent de s’exécuter!
Les sujets problématiques sont:
Thread [<17> WebViewCoreThread] (Running)
Thread [<25> CookieSyncManager] (Running)
Thread [<19> http0] (Running)
Thread [<29> http1] (Running)
Thread [<31> http2] (Running)
Thread [<33> http3] (Running)
Mettre en pause chacun de ces threads et vérifier ce qu’il est en train de faire:
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
Je me demande comment puis-je dire à la Looper
dans chacun de ces fils d'arrêter.
J'ai essayé d'appeler webView.destroy()
dans la méthode onPause()
de l'activité, Mais cela n'avait aucune influence.
Lorsque je désactive l’appel pour l’ouverture d’une page Web dans la WebView (webView.loadUrl(...)
), ces threads ne sont naturellement pas lancés et, par conséquent, ne restent pas activés après avoir quitté l’activité.
Des idées sur la façon dont je peux faire en sorte que les fils de WebView
cessent après avoir quitté Leur activité?
Vous devriez pouvoir arrêter/reprendre ces discussions en appelant onPause/onResume dans la vue Web.
Celles-ci sont cependant cachées, vous devrez donc le faire par réflexion. Le code suivant a fonctionné pour moi:
Class.forName("Android.webkit.WebView").getMethod("onPause", (Class[]) null).invoke(webView, (Object[]) null);
Où webView est l'instance de WebView.
Voir aussi: http://code.google.com/p/Android/issues/detail?id=10282
Ma solution, dans la classe de visualisation Web étendue (testée sous 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) {}
}
}
Une solution simple et propre qui fait le travail:
@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;
}
Jetez un oeil à ce fil andev.org ( problème avec WebViewCoreThread ).
Voir la réponse ... Objet: Problème WebViewCoreThread - Postby potatoho
2) Pour suspendre flash, vous devez appeler les méthodes cachées WebView.onPause ()/WebView.onResume ().
3) Pour suspendre WebViewCoreThread, utilisez WebView.pauseTimers ()/WebView.resumeTimers ().
J'ai ignoré le onPause/onResume, mais j'ai implémenté webView.pauseTimers()
et webView.resumeTimers()
et il arrête au moins la purge du processeur.
J'ai également ajouté CookieSyncManager.getInstance().stopSync()
/startSync
à mon onPause/onResume.
Qu'en est-il de WebView.destroy ()? Cela semble être de nettoyer les choses ou moi sans faire des appels de réflexion géniaux.
Merci pour ces informations, j'ai eu ce problème en suspendant les sons dans mon swf sur webView lorsque j'appuie sur le bouton de verrouillage du téléphone, onPause et onResume joue toujours mon swf lorsque j'appuie sur le bouton de déverrouillage mais l'activité n'est toujours pas visible placez-les sur onWindowFocusChanged si vous souhaitez suspendre et reprendre la lecture des sons swf dans 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);
}
En fait, utiliser webView.destroy(), onPause(), clear**()
ne peut pas encore arrêter Webcore et ses threads associés.
Pratiquement, un moyen idéal consiste à définir l'activité où WebView réside dans un processus indépendant, de sorte que lorsque l'activité est terminée, tous les threads, y compris Webcore, soient détruits.
C'est la façon dont j'ai employé. Peut-être que cela vous est également utile.
Les solutions ci-dessus ont échoué pour moi sur Samsung Galaxy S avec Android 2.3.3 .
webview.loadUrl("file:///Android_asset/nonexistent.html");
Je force la webview à charger un fichier HTML non existant. Cela semble forcer la vue Web à nettoyer les choses.
J'ai dû appeler onDestroy de la WebView pour effacer la mémoire spécifiquement pour la vue Web. J'étais en train de charger le flash et cela tue mon application lorsque nous revenons à cette activité avec une vue Web. Flash vous dévorera si vous ne détruisez pas votre WebView CHAQUE FOIS que vous avez terminé.
Définir une méthode:
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");
}
}
}
appelez ensuite hiddenWebViewMethod("onPause");
pour arrêter le chargement et hiddenWebViewMethod("onResume");
pour le reprendre.