我正在使用Phonegap在Android WebApp中工作。要退出应用程序,我将从JavaScript代码中调用navigator.app.exitApp
。
我试图找到此方法的文档页面,但它不存在。然后我下载了适用于Android的Phonegap源代码,但是我没有找到该库从本机代码退出应用程序的位置和方式。我没有时间这样做,所以我决定自己测试一下。
我的应用程序有一个DroidGap活动(使用singleInstance标志启动),还有一个服务和一个广播接收器。用户必须能够关闭GUI,但我想保持服务和其他一切运行。所以我想做的只是完成活动,而不是调用System.exit
。
现在这里有奇怪的部分。我已经在模拟器中对此进行了测试,并且DroidGap活动似乎以我想要的方式关闭(onDestroy被触发)并且服务保持运行。但是,尽管活动已关闭,并且任务管理器中不再显示应用程序图标,但JavaScript计时器仍在运行。我已经三次检查了这个。我想相信活动是在后台,但它不能是:它是作为singleInstance启动的,当我再次打开应用程序时它会显示初始页面(它在不同的页面中关闭)。
为什么会这样?我应该编写插件来直接调用finish
活动吗?
提前致谢。
答案 0 :(得分:2)
我一直在调查这几个小时,所以我会在这里发布我的发现。
在每个Android WebApp中,不仅是Phonegap应用程序,每当您拥有WebView时,都会产生两个线程:WebViewCoreThread
和WebViewWorkerThread
。它们显示在DDMS中。我一直在阅读Android源代码,我已将此线程的创建跟踪到WebViewCore.java
文件。显然,每个应用程序进程只启动两个线程,并且它们由应用程序中的每个WebView共享。
当包含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代码可能会崩溃。
答案 1 :(得分:0)
你需要在调用navigator.app.exitApp()
之前明确地终止计时器。此问题也在here进行了讨论。
希望这有助于......:)