【发布时间】:2015-11-12 23:20:55
【问题描述】:
我目前正在开发适用于 Android 的应用程序。要求之一是有关如何使用应用程序的大量日志记录。更具体地说,应该记录用户何时关闭应用程序。此日志记录由服务器交互组成。关于我偶然发现的具体要求:
Detect Application Exit(1) 和 Detect application Exit (2)
这两个问题都有一个接受的答案,依赖于Service#onTaskRemoved(Intent)。
在我的情况下,这个解决方案似乎不起作用,即在这个方法中启动的AsyncTasks 只是偶尔执行。更具体地说,onPreExecute 被执行总是,但doInBackground 不是。我在安装了 Android 6 (Marshmallow) 的 Nexus 5 上对此进行了测试。
public class SomeService extends Service {
@Override
public IBinder onBind( Intent aIntent ) {
return null;
}
@Override
public void onTaskRemoved(Intent aRootIntent ) {
new DoSomethingTask().executeOnExecutor( Asyntask.THREAD_POOL_EXECUTOR );
}
private static final class DoSomethingTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
Log.e( DoSomethingTask.class.getName(), "This is executed always");
}
@Override
protected Void doInBackground( Void... aParams ) {
Log.e( DoSomethingTask.class.getName(), "This appears to be executed only sometimes... ");
// here an actual call to a Rest API should be made to inform the server that the user has closed the application.
}
@Override
protected void onCancelled( Void result ) {
super.onCancelled( result );
Log.e( DoSomethingTask.class.getName(), "Never invoked" );
}
@Override
protected void onCancelled() {
super.onCancelled();
Log.e( DoSomethingTask.class.getName(), "Never invoked" );
}
}
}
除了上述代码示例之外,这里是我尝试的所有内容的概述:
- 我尝试了各种
onStartCommand选项(START_STICKY、START_NOT_STICKY 等),但均未成功。 - 我也试过在
onTaskRemoved方法中重启服务,然后在onStartCommand中执行AsyncTask。 - 在
onTaskRemoved方法中启动IntentService(在其AsyncTask方法中启动AsyncTask)也不能解决问题。 - 将
BroadcastReceiver与本地广播 (LocalBroadcastManager#sendBroadcast) 结合使用也不起作用(我仔细检查了广播接收器是否已有效注册为已发送广播的接收器)。
编辑:
我还查看了Application 类中的回调:
- onTerminate :此方法仅在模拟环境中调用,因此无用
- onTrimMemory(int) : 此方法可用于检测应用何时进入后台,但对于应用何时退出没有明确的情况。
我可以保留一个活动堆栈(将在Activity#onPause() 等中更新)。但这需要在每一个Activity 中做大量工作,而不是上面的Service 方法,它只涉及一个地方的干扰。
【问题讨论】:
-
您可以通过扩展 Application 类并覆盖 onTerminate() onDestroy() onLowMemory() 和类似的东西来做到这一点。
-
我也试过了,但我忘了在帖子里提到。我现在已经在底部完成了,请参阅 Edit 部分。
标签: android android-asynctask android-service android-broadcast intentservice