我已经调查了几个小时,所以我将在这里发布我的发现。
在每个 Android WebApp 中,不仅是 Phonegap 应用程序,只要你有一个 WebView,就会产生两个线程:WebViewCoreThread
和WebViewWorkerThread
. 它们显示在 DDMS 中。我一直在阅读 Android 源代码,并且我已经将这个线程的创建跟踪到WebViewCore.java
文件中。显然,每个应用程序进程只启动了两个线程,它们由应用程序中的每个 WebView 共享。
恕我直言,在屏幕中使用视图意味着产生线程这一事实是非常糟糕的设计。如果这个字段需要做像启动线程一样复杂的事情,那么它应该被更好地设计为 WebViewActivity 或 WebWiewFragment 。在任何情况下,创建线程的类也应该负责在不再需要它时完成它。不幸的是,事实并非如此。
当包含 WebView 的 Activity 关闭但应用程序进程仍在运行时(可能是因为您有其他组件,如服务,或者操作系统尚未杀死它),这些线程将继续运行。核心线程将继续执行您在应用程序中设置的计时器。再次创建活动时,线程将被重用。
作为旁注,请注意这如何允许在后台运行 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 代码可能会崩溃。