如何知道什么时候我的应用程序被关闭?

我需要知道当用户杀死我的应用程序(强制停止)。我一直在阅读 android 的生命周期,它具有 onStop()onDestroy()功能,这些功能与用户在我的应用程序上结束的每个活动相关,但不是当用户强制停止或杀死我的应用程序时。

有没有办法知道用户什么时候关闭应用程序?

84779 次浏览

there's no way to determine when a process is killed. From How to detect if android app is force stopped or uninstalled?

When a user or the system force stops your application, the entire process is simply killed. There is no callback made to inform you that this has happened.

When the user uninstalls the app, at first the process is killed, then your apk file and data directory are deleted, along with the records in Package Manager that tell other apps which intent filters you've registered for.

Create a Application class

onCreate()
Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created.
onLowMemory()
This is called when the overall system is running low on memory, and actively running processes should trim their memory usage.
onTerminate()
This method is for use in emulated process environments.

Even if you are application Killed or force stop, again Android will start your Application class

I have found one way to do this.....

  1. Make one service like this

    public class OnClearFromRecentService extends Service {
    
    
    @Override
    public IBinder onBind(Intent intent) {
    return null;
    }
    
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("ClearFromRecentService", "Service Started");
    return START_NOT_STICKY;
    }
    
    
    @Override
    public void onDestroy() {
    super.onDestroy();
    Log.d("ClearFromRecentService", "Service Destroyed");
    }
    
    
    @Override
    public void onTaskRemoved(Intent rootIntent) {
    Log.e("ClearFromRecentService", "END");
    //Code here
    stopSelf();
    }
    }
    
  2. Register this service in Manifest.xml like this

    <service android:name="com.example.OnClearFromRecentService" android:stopWithTask="false" />
    
  3. Then start this service on your splash activity

    startService(new Intent(getBaseContext(), OnClearFromRecentService.class));
    

And now whenever you will clear your app from android recent Then this method onTaskRemoved() will execute.

NOTE: In Android O+ this solution only works when the app is full-time in foreground. After more than 1 minute with the app in background, the OnClearFromRecentService (and all other Services running) will be automatically force-killed by the system so the onTaskRemoved() will not be executed.

I have alternate idea.i have same problem like you.above methods not fix.my problem : "i want to clear all saved data entire app,when user completely close the app"

So, i added clear() & clear saved data(from shared preference or tinyDB) in Application class.

After digging into this problem I found a solution that might help you:

All you need to do is check on the onDestroy method of your BaseActivity that is extended by all your activities whether the last running activity of the stack is from your package or not with the following code:

ActivityManager activityManager = (ActivityManager) getSystemService( ACTIVITY_SERVICE );


List<ActivityManager.RunningTaskInfo> taskList = activityManager.getRunningTasks( 10 );


if ( !taskList.isEmpty() )
{
ActivityManager.RunningTaskInfo runningTaskInfo = taskList.get( 0 );
if ( runningTaskInfo.topActivity != null &&
!runningTaskInfo.topActivity.getClassName().contains(
"com.my.app.package.name" ) )
{
//You are App is being killed so here you can add some code
}
}

This might help many, who wants to know if the app is terminated or not The best way is to keep data in one static variable for eg: public static string IsAppAvailable;

the specialty about the static variable is that the data in the static variable contains till the app is in foreground or background, once the app is killed the data in the static variable is erased. Basically, the static variable is reinitialized when the app is freshly created

Create one static class file say Const

namespace YourProject
{
public static class Const
{
public static string IsAppAvailable;
}
}

In MainActivity

   protected override void OnResume()
{
if(string.IsNullOrWhiteSpace(Const.IsAppAvailable))
{
//Your app was terminated
}
Const.IsAppAvailable = "Available"
}

Hope this is helpful to the developers :) Happy coding

for some cases, you can create splash screen page to determine if app has been killed previously by system.

it basically a screen with intent filter main/launcher, and will be finished, and changed to main activity.

so, every time user visit splashScreen, it shows that the app has been killed before, and you can do anything you want to handle.

sample code:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="id.gits.yourpackage">


<application
android:name=".App">
<activity android:name=".SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />


<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

SplashActivity:

class SplashActivity : AppCompatActivity() {
override fun onCreate() {
super.onCreate()
doSomethingAfterAppKilled()
}
}

I found something that worked for me (in xiaomi), you have to make a class for example "MyObserver", and call this in your on create as follows: getLifecycle().addObserver(MyObserver(this)).

class MyObserver(var context: Context) : LifecycleObserver {


@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun disconnect() {
Log.e("APP", "killed")
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun pause(){
Log.e("APP","Paused") //para pausa
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun resume(){
Log.e("APP","Resumed") //para retorno de pausa
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stop(){
Log.e("APP","Stopped") // para cambio de actividad
}
}

I found a way that can detect app kill: use ActivityLifecycleCallbacks to counter activity active number

There are some situations:

  • for User kill( use App switcher ): counter activity number/taskstack etc
  • (unspecify)for Android Framework kill(Low Memory etc):
  • (unspecify)for Native kill(Process.kill kill signal): use native
class StarterApplication: android.app.Application() {
var counterActivityCreate = 0
override fun onCreate() {
super.onCreate()
Log.d(TAG, "onCreate: ")


registerActivityLifecycleCallbacks(object: android.app.Application.ActivityLifecycleCallbacks{
override fun onActivityCreated(activity: android.app.Activity, savedInstanceState: android.os.Bundle?) {
Log.d(TAG, "onActivityCreated: ${activity.javaClass.name}")
counterActivityCreate++
}


override fun onActivityStarted(activity: android.app.Activity) {
Log.d(TAG, "onActivityStarted: ${activity.javaClass.name}")
}


override fun onActivityResumed(activity: android.app.Activity) {
Log.d(TAG, "onActivityResumed: ${activity.javaClass.name}")
}


override fun onActivityPaused(activity: android.app.Activity) {
Log.d(TAG, "onActivityPaused: ${activity.javaClass.name}")
}


override fun onActivityStopped(activity: android.app.Activity) {
Log.d(TAG, "onActivityStopped: ${activity.javaClass.name}")
}


override fun onActivitySaveInstanceState(activity: android.app.Activity, outState: android.os.Bundle) {
Log.d(TAG, "onActivitySaveInstanceState: ${activity.javaClass.name}")
}


override fun onActivityDestroyed(activity: android.app.Activity) {
Log.d(TAG, "onActivityDestroyed: ${activity.javaClass.name}")
counterActivityCreate--
if(counterActivityCreate == 0){
Log.d(TAG, "onActivityDestroyed: all activity destroyed")


}
}


})
}