Android应用在被杀时不会调用"onDestroy()"(ICS)

The*_*ant 21 android ondestroy android-4.0-ice-cream-sandwich

我正在开发一个使用蓝牙通信的Android应用程序(使用一个propetary协议),我需要抓住应用程序被杀的那一刻.

我想使用"onDestroy()"方法,但每次应用程序被杀死时都不会调用它.我注意到当我按下后退按钮时会调用它,有时只有当我从任务管理器中删除应用程序时才会调用它.

问题是:我怎样才能抓住应用程序被杀之前的那一刻?

这是我试图使用的代码:

@Override
public void onDestroy() {
    sendMessage(msg);
    Log.d("SampleApp", "destroy");
    super.onDestroy();
}

@Override
public void finish(){

    sendMessage(msg);
    Log.d("SampleApp", "finish");
    super.finish();
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,每次我从任务管理器关闭应用程序时都不会调用finish()并且不会调用onDestroy.

我怎么处理这个?

Rag*_*ood 15

如文档中表示这里,没有保证的onDestroy()永远不会被调用.相反,使用onPause()可以在应用程序进入后台时执行您想要执行的操作,并且仅在您的应用程序被终止时将该代码留在onDestroy()中.

编辑:

从您的评论中,您似乎希望在应用程序进入后台时运行一些代码,但如果因为您启动了一个意图而进入后台则不会.AFAIK,Android中没有默认处理此方法的方法,但您可以使用以下内容:

有一个布尔像:

boolean usedIntent = false;
Run Code Online (Sandbox Code Playgroud)

现在在使用intent之前,将boolean设置为true.现在在onPause()中,将intent case的代码移动到像这样的if块中:

if(usedIntent)
{
//Your code
}
Run Code Online (Sandbox Code Playgroud)

最后,在你的onResume()中,再次将布尔值设置为false,以便它可以通过非意图的方式处理你的应用程序被移动到后台.


Dev*_*red 14

如果进程通过外部方式终止(即因内存原因而被终止或用户强制停止应用程序),您的应用程序将不会收到任何额外的回调.当您的应用程序进入应用程序清理的后台时,您将不得不处理您收到的回调.

finish()只有当用户从Activity按下BACK按钮时系统才会调用它,尽管应用程序通常会直接调用它来保留Activity并返回上一个Activity.这在技术上不是生命周期回调.

onDestroy()只有在调用时才调用Activity finish(),因此主要仅在用户点击BACK按钮时调用.当用户点击HOME按钮时,前景Activity仅通过onPause()onStop().

这意味着Android不会向活动提供太多反馈,以区分用户回家与移动到另一个活动(来自您的应用程序或任何其他活动); 活动本身只知道它不再在前台.Android应用程序是一个松散的活动集合,而不是一个紧密集成的单一概念(就像你可能习惯在其他平台上一样)所以没有真正的系统回调可以知道你的应用程序作为一个整体被提出或移动的时间向后.

最后,如果它依赖于您的应用程序中的任何活动是否在前台的知识,我会建议您重新考虑您的应用程序架构,但根据您的需要,可能还有其他方式更友好的框架来实现这一点.一种选择是Service在应用程序内部实现绑定,每个Activity绑定在活动时(即在onStart()和之间onStop()).这为您提供的是能够利用绑定Service仅在客户端绑定的情况下生存的事实,因此您可以监视服务的方法onCreate()onDestroy()方法,以了解当前前台任务何时不属于您的应用程序.

您可能还会发现Dianne Hackborn撰写的这篇文章有趣地介绍了Android架构以及Google认为应该如何使用它.


Nav*_*r M 5

我刚刚解决了类似的问题。

如果只是在通过从最近的应用程序列表中滑动来终止应用程序时停止服务,您可以执行以下操作。

在清单文件中,保留服务stopWithTask标记。true喜欢:

<service
    android:name="com.myapp.MyService"
    android:stopWithTask="true" />
Run Code Online (Sandbox Code Playgroud)

但正如您所说,您想取消注册侦听器并停止通知等,我建议采用这种方法:

  1. 在清单文件中,保留服务stopWithTask标记。false喜欢:

    <service
        android:name="com.myapp.MyService"
        android:stopWithTask="false" />
    
    Run Code Online (Sandbox Code Playgroud)
  2. 现在在您的MyService服务中,覆盖 method onTaskRemovedstopWithTask(仅当设置为 时才会触发false)。

    public void onTaskRemoved(Intent rootIntent) {
    
        //unregister listeners
        //do any other cleanup if required
    
        //stop service
        stopSelf();  
    }
    
    Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅此问题,其中也包含代码的其他部分。

  1. 启动服务如下

startService(new Intent(this, MyService.class));

希望这可以帮助。