22

我正在使用蓝牙通信(使用专有协议)开发一个 android 应用程序,我需要捕捉应用程序被杀死的时刻。

我想使用“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();
}

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

我该如何处理?

4

3 回答 3

15

Your application will not receive any additional callbacks if the process it terminated by external means (i.e. killed for memory reasons or the user Force Stops the application). You will have to make do with the callbacks you received when you app went into the background for your application cleanup.

finish() is only called by the system when the user presses the BACK button from your Activity, although it is often called directly by applications to leave an Activity and return to the previous one. This is not technically a lifecycle callback.

onDestroy() only gets called on an Activity as a result of a call to finish(), so mainly only when the user hits the BACK button. When the user hits the HOME button, the foreground Activity only goes through onPause() and onStop().

This means that Android doesn't provide much feedback to an Activity to differentiate a user going Home versus moving to another Activity (from your app or any other); the Activity itself simply knows it's no longer in the foreground. An Android application is more a loose collection of Activities than it is a tightly integrated singular concept (like you may be used to on other platforms) so there are no real system callbacks to know when your application as a whole has been brought forward or moved backward.

Ultimately, I would urge you to reconsider your application architecture if it relies on the knowledge of whether ANY Activity in your application is in the foreground, but depending on your needs, there may be other ways more friendly to the framework to accomplish this. One option is to implement a bound Service inside of your application that every Activity binds to while active (i.e. between onStart() and onStop()). What this provides you is the ability to leverage the fact that a bound Service only lives as long as clients are bound to it, so you can monitor the onCreate() and onDestroy() methods of the Service to know when the current foreground task is not part of your application.

You might also find this article written by Dianne Hackborn to be interesting covering in more detail the Android architecture and how Google thinks it ought to be used.

于 2012-07-13T16:11:35.850 回答
15

正如此处的文档中所述,不能保证永远会调用 onDestroy()。相反,当应用程序进入后台时,使用onPause()来执行您想要执行的操作,并在 onDestroy() 中只保留您想要在应用程序被终止时运行的代码。

编辑:

从您的评论来看,您似乎希望在您的应用程序进入后台时运行一些代码,但如果它因为您启动了一个意图而进入后台,则不是。AFAIK,默认情况下Android中没有处理这个的方法,但你可以使用这样的东西:

有一个布尔值,如:

boolean usedIntent = false;

现在在使用意图之前,将布尔值设置为 true。现在在您的 onPause() 中,将意图案例的代码移动到这样的 if 块中:

if(usedIntent)
{
//Your code
}

最后,在您的 onResume() 中,再次将布尔值设置为 false,以便它可以正确地处理您的应用程序被非意图方式移动到后台的情况。

于 2012-07-13T15:51:22.703 回答
2

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

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

在您的清单文件中,将标志保留stopWithTasktrue服务。喜欢:

<service
    android:name="com.myapp.MyService"
    android:stopWithTask="true" />

但是正如您所说,您要注销侦听器并停止通知等,我建议采用这种方法:

  1. 在您的清单文件中,将标志保留stopWithTaskfalse服务。喜欢:

    <service
        android:name="com.myapp.MyService"
        android:stopWithTask="false" />
    
  2. 现在在您的MyService服务中,覆盖方法onTaskRemoved。(仅当stopWithTask设置为时才会触发false)。

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

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

  1. 启动服务如下

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

希望这可以帮助。

于 2017-11-16T08:39:24.900 回答