我一直在研究这个了几个小时,所以我会在这里发布我的发现。
在每个Android Web应用程序中,不仅Phonegap应用程序,只要有WebView,就会产生两个线程:WebViewCoreThread
和WebViewWorkerThread
。它们显示在DDMS中。我一直在阅读Android资源,并且已经将此线程的创建跟踪到WebViewCore.java
文件。显然,每个应用程序进程只启动两个线程,并且它们由应用程序中的每个WebView共享。
恕我直言,在屏幕上使用视图意味着产卵线程的事实是非常糟糕的设计。如果这个字段需要像开始一个线程一样复杂,那么它应该更好地设计为WebViewActivity或WebWiewFragment。在任何情况下,创建线程的类也应负责在不再需要时完成它。这不幸的是并非如此。
当包含WebView的活动关闭但应用程序进程仍在运行时(可能是因为您有其他组件,或者操作系统尚未终止它),这些线程仍在运行。核心线程将继续执行您在应用中设置的计时器。当活动再次创建时,线程将被重用。作为一个便笺,请注意这是如何在后台运行javascript代码而不必保持活动显示的。
我尝试了一些变通办法在这个问题暴露一个普通WevView的:WebView threads never stop (WebViewCoreThread, CookieSyncManager, http[0-3]),
,但由于一些未知的原因,它不与PhoneGap的工作。我试图重写我的DroidGap子是这样的:
@Override
public void onDestroy(){
System.out.println("Activity destroyed");
if(appView != null){ //This is a protected reference to the `CordovaWebView`, extending `WebView`
//First attempt
try {
Class.forName("android.webkit.WebView").getMethod("onPause", (Class[]) null).invoke(appView, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
//Second attempt
appView.pauseTimers();
}
super.onDestroy();
}
因此,我终于做到了在退出应用前,确保所有的计时器都从JavaScript代码取消。然而,人们会希望在Android操作系统代码中修正这个问题,或者在Phonegap中进行修补,因为即使在最好的情况下,这些线程也浪费了当没有显示网页时真正不需要的资源。而在最糟糕的情况下,一些与DOM相关的JavaScript代码可能会崩溃。
只是为了分享,我经历过同样的事情。不知何故,尽管应用程序已关闭,并且如果我们有一些计时器(例如使用setInterval),它有时仍会继续运行。我的理论是,应用程序被销毁,但webview不知何故仍然在执行的内存中? – wmfairuz 2013-04-09 11:15:19
我目前正在真实设备上调试它。有一个“WebViewCoreThread”在关闭活动后仍然在运行。我发现这个问题,可能与此有关:http://stackoverflow.com/q/2040963/813951 – 2013-04-09 11:23:01
这很奇怪。应用程序被销毁后,webview如何仍然活着? – wmfairuz 2013-04-09 11:34:24