Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Phonegap:关闭DroidGap活动后javascript计时器仍在运行_Java_Javascript_Android_Cordova_Exit - Fatal编程技术网

Phonegap:关闭DroidGap活动后javascript计时器仍在运行

Phonegap:关闭DroidGap活动后javascript计时器仍在运行,java,javascript,android,cordova,exit,Java,Javascript,Android,Cordova,Exit,我在使用Phonegap的Android网络应用程序中工作。要退出应用程序,我要从JavaScript代码中调用navigator.app.exitApp 我试图找到此方法的文档页,但它不存在。然后我下载了Android的Phonegap源代码,但是我没有找到这个库从本地代码中退出应用程序的位置和方式。我没有时间做这个,所以我决定自己测试一下 我的应用程序有一个DroidGap活动(使用singleInstance标志启动),但也有一个服务和一个广播接收器。用户必须能够关闭GUI,但我希望保持服

我在使用Phonegap的Android网络应用程序中工作。要退出应用程序,我要从JavaScript代码中调用
navigator.app.exitApp

我试图找到此方法的文档页,但它不存在。然后我下载了Android的Phonegap源代码,但是我没有找到这个库从本地代码中退出应用程序的位置和方式。我没有时间做这个,所以我决定自己测试一下

我的应用程序有一个DroidGap活动(使用singleInstance标志启动),但也有一个服务和一个广播接收器。用户必须能够关闭GUI,但我希望保持服务和其他一切运行。所以我想做的是只完成活动,而不是调用
System.exit

现在是奇怪的部分。我已经在模拟器中对此进行了测试,DroidGap活动似乎按照我希望的方式关闭(onDestroy被触发),并且服务一直在运行。但是,尽管活动已关闭,并且应用程序图标不再显示在任务管理器中,但不知何故JavaScript计时器仍在运行。我已经检查了三遍了。我想相信该活动是在后台进行的,但不可能:它是作为singleInstance启动的,当我再次打开应用程序时,它会显示初始页面(它在另一个页面中关闭)

为什么会发生这种情况?我是否应该编写一个插件,在活动中直接调用
finish


提前感谢。

您需要在调用
navigator.app.exitApp()
之前明确终止计时器。对这一问题也进行了讨论


希望这能有所帮助……:)

我已经对此进行了几个小时的调查,所以我将在这里公布我的发现

在每个Android Web应用程序中,不仅仅是Phonegap应用程序,只要你有一个WebView,就会产生两个线程:
WebViewCoreThread
WebViewWorkerThread
。它们显示在DDMS中。我一直在阅读Android源代码,我一直在跟踪这个线程的创建,一直到
WebViewCore.java
文件。显然,每个应用程序进程只启动两个线程,应用程序中的每个WebView都共享这些线程

事实上,在屏幕中使用视图意味着产生线程是非常糟糕的设计。如果这个字段需要做像启动线程一样复杂的事情,那么它应该更好地设计为WebViewActivity或WebWiewFragment。在任何情况下,创建线程的类也应该负责在不再需要它时完成它。不幸的是,情况并非如此

当包含WebView的活动关闭但应用程序进程仍在运行时(可能是因为您有其他组件,如服务,或者操作系统尚未终止它),这些线程将保持运行。核心线程将继续执行您在应用程序中设置的计时器。再次创建活动时,将重用线程

作为旁注,请注意这如何允许在后台运行javascript代码,而不必显示活动

我尝试了一些解决方法,用于在这个问题中公开的常规WevView:

但不知什么原因,它不适用于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不知何故仍保留在内存中。我正在实际设备上调试它。关闭活动后,仍有一个
WebViewCoreThread
在运行。我发现这个问题,可能是相关的:这很奇怪。在应用程序被销毁后,webview如何能够保持活动状态?应用程序进程不会被销毁,因为有更多组件正在运行。WebView和活动已销毁,但与WebView关联的线程仍在运行(与在常规活动中启动新线程并完成活动时相同),您似乎回答了自己的问题:)谢谢,我会的。但这是一个解决办法。我希望操作系统或Phonegap能够处理它。谢谢分享。您是如何取消所有计时器的?我有一个问题,我的WebView被一些用户发送到后台,并被Android系统杀死。我看不到手动取消所有计时器的可能性…@ottel142我将开始通过javascript文件搜索
setInterval
,并确保每个调用结果都存储在一个变量中,以便以后可以使用
clearInterval
取消它们。与
setTimeout
调用相同。另一种可能是在活动的
onDestroy
中调用
System.exit
Process.killProcess
,这将终止整个主进程。如果您需要一个服务,您可能希望在另一个流程中启动它,这样它就不会随着活动一起被终止。