如何在安卓系统中检测应用程序退出?

8
如何在应用程序退出时执行一些代码?我想在应用程序退出时删除临时数据。当我说应用程序退出时,意味着应用程序不是在后台最小化运行,而是完全关闭。
我尝试创建一个运行在单独进程中的服务,该服务检查应用进程是否未运行,然后删除临时文件夹。使用此方法,由于进程仍在以最低优先级运行,因此不总是删除临时文件夹。
我无法在OnDestroy()中实现这一点。
服务代码:
[Service(Process = "com.lobomonitor")]
[IntentFilter(new string[] { "com.androidgui.ProcessMonitorService" })]
public class ProcessMonitorService : Service
{
    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        Thread processThread = new Thread(() =>
            {
                ActivityManager actManager = (ActivityManager) this.GetSystemService(ActivityService);
                while (true)
                {
                    Thread.Sleep(1000);
                    IList<ActivityManager.RunningAppProcessInfo> procList = actManager.RunningAppProcesses;
                    procList.Any(i => i.ProcessName.Equals("com.androidgui"));
                    if (!procList.Any(i => i.ProcessName.Equals("com.androidgui")))
                    {
                            FolderManager.Singleton.DeleteTempFolder();
                            break;
                    }
                }
            });
        processThread.Start();
        return StartCommandResult.RedeliverIntent;
    }

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }
}

https://dev59.com/pWQo5IYBdhLWcg3wI8ZV - Rachel Gallen
1
https://dev59.com/AWw15IYBdhLWcg3wVKN1 - Rachel Gallen
应用程序的生命周期由Android操作系统管理,我认为不可能检测到它。https://dev59.com/w3I-5IYBdhLWcg3wED5V - naveejr
2
我无法使用Activity生命周期中的任何方法,因为如果我在Activity中打开文件并删除临时文件夹,外部查看器将显示错误消息,指出文件不存在(例如Polaris)。 - Xzil0
https://dev59.com/kZbfa4cB1Zd3GeqPnQR9#61101320 - Erfan Eghterafi
2个回答

18

我不知道这是否有帮助,但是如果您关闭应用程序,那么在后台运行的服务会调用该方法:

@Override
public void onTaskRemoved(Intent rootIntent){

    super.onTaskRemoved(rootIntent);
}
例如,我曾经有一个运行服务的应用程序。当我杀掉应用程序时,服务也停止了,但我想让它继续运行。通过使用onTaskRemoved,我能够安排重新启动服务:

例如,我曾经有一个运行服务的应用程序。当我杀掉应用程序时,服务也停止了,但我想让它继续运行。通过使用onTaskRemoved,我能够安排重新启动服务:

@Override
public void onTaskRemoved(Intent rootIntent){
    Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
    restartServiceIntent.setPackage(getPackageName());

    PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmService.set(
            AlarmManager.ELAPSED_REALTIME,
            SystemClock.elapsedRealtime() + 1000,
            restartServicePendingIntent);

    super.onTaskRemoved(rootIntent);
}

作用是 -> 我正在关闭我的应用程序 -> 服务查看任务正在被移除并调用onTaskRemoved -> 我在1秒钟内安排重新启动服务 -> 服务死亡 -> 一秒后它会被唤醒 -> 结果:应用程序已被杀死,我执行了重启服务的代码,因此它仍在后台运行(仅在首选项-> 应用程序中作为进程可见)

http://developer.android.com/reference/android/app/Service.html

void     onTaskRemoved(Intent rootIntent)

如果服务正在运行并且用户已经删除来自该服务应用程序的任务,则调用此方法。


谢谢。这就是我想要的行为。我只是在OnTaskRemoved()中调用了FolderManager.Singleton.DeleteTempFolder();。 - Xzil0
谢谢,我一直在寻找这样的东西。 - takluiper

2
我的经验表明,大多数应用程序实际上并不需要您所描述的退出回调。
Android的做法通常可以很好地解决问题,这是组件级别(Activity、Service 等)的生命周期管理。
一些应用程序允许通过按钮、菜单等方式提供“退出”功能,在用户激活后允许应用程序关闭所有打开的组件并基本关机。
但是,如果确实需要退出回调,最接近的可能是创建一个专用服务,除了 onDestroy() 函数外没有其他逻辑,并在应用程序启动时激活它,而永远不关闭它!
class ExitListenerService extends Service {
    @Override
    public void onDestroy() {
        super.onDestroy();
        // App exit logic here. Not deterministic!
    }       
}

很有可能此服务将是操作系统中最后一个被回收的组件。在大多数情况下,这应该是可行的,对于我来说也很好用。但是它并不是100%保证。

但是...如果您一定要有一个无懈可击的解决方案,我所知道的唯一其他方法是创建一个对等应用程序,并称之为看门狗,定期唤醒以检查主要应用程序是否仍在运行,如果没有运行,将激活退出逻辑。

要运行此最后一项检查,您需要调用:

  List<RunningAppProcessInfo> runningApps = activityManager.getRunningAppProcesses();

并迭代运行中的应用程序,寻找自己的应用程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接