一键退出App相信是很多Android开发者都需要去实现的需求,但到底该如何干净利索地实现它呢?来吧,撸一个试试。
首先需要明确的一点是,完全退出App本质来讲分为两个部分。
关闭该App所有的Activity。
结束该App的进程。
接下来我们就分别实现这两个部分。
关闭所有Activity
第一步,我们需要关闭所有的Activity。
1.Activity启动模式
在Activity启动模式详解中,我们详细讲解了Activity的启动模式,还不熟悉的小伙伴可以先看一下这篇文章。
首先我们把App的入口Activity采用SingleTask启动模式,或者加上标记Intent.FLAG_ACTIVITY_CLEAR_TOP。
当需要退出App时,直接启动App入口的Activity。因为该Acitivity是SingleTask模式,所以系统会帮助我们将该Activity上面的其他Activity全部关闭移除,并把该Activity放置在栈顶。
1 | @Override |
接着系统会调用该Activity的onNewIntent()方法,所以我们再在这个方法里判断是否有退出App的标识,如果有则关闭自身。
1 | @Override |
这种方法使用简单便捷。但是必须要规定App入口的Activity采用SingleTask模式,而且如果App里有多任务栈(SingleInstance模式启动),就无能为力了。
2.系统任务栈
我们可以同过ActivityManager获取当前系统的任务栈,然后把栈内的所有Activity逐个关闭。
1 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
这种方法使用简单便捷。但是只能在Android 5.0以上使用,而且同样,对多任务栈(SingleInstance模式启动)无能为力。
3.BroadcastReceiver
我们也可以通过广播监听的方式来实现关闭所有Activity。
首先自定义一个广播接收器,专门用来关闭Activity。
1 | public class ExitAppReceiver extends BroadcastReceiver { |
然后在每个Activity里注册广播接收器,这里也可以用一个BaseActivity来实现。
1 | public class BaseActivity extends Activity { |
最后在需要退出App时,发送广播。
1 | context.sendBroadcast(new Intent("com.chen.exit")); |
这里需要注意的是,该方法只能实现用户角度上的一键退出。即只能退出所有Activity,但无法再接着下面的退出整个App进程的操作。因为发送广播后,并不能保证在第一时间接收到广播,所以不能直接在发送后关闭整个进程。
这种方法可以实现多任务栈情况下的一键退出,但需要在每个Activity里注册广播接收器。最关键的是,它无法做到最终终止App进程。
4.重写Application
我们可以在Manifest里配置自定义的Application子类。
1 | <application |
接着在MyApplication里建立一个Activity的链表结构,来保存正在运行的Activity实例。当需要一键退出时,把链表里的所有Activity实例逐个退出即可。
1 | public class MyApplicaiton extends Application { |
接着调用一键退出方法。
1 | private MyApplicaiton app; |
该方法同样可以实现多任务栈情况下的一键退出,但它需要Activity经历正常的生命周期,即创建时调用onCreate(),结束时调用onDestroy()。
5.EventBus或者RxBus
我们也可以借助EventBus或者RxBus来实现这个功能,这里以RxBus为例。
首先,在每个Activity的onCreate()方法里注册RxBus,并判断响应动作是否为退出App,如果是则关闭自己。这里要记得要在onDestroy()方法里取消订阅。
1 | public class BaseActivity extends Activity { |
接着在需要退出App时,发送退出事件。
1 | RxBus.getInstance().post("exitApp"); |
如果项目里已经接入有EventBus或RxBus,可以用该方法简单便捷地实现这个功能。当然,如果项目里没有接入,不建议为该功能特地接入。
结束App进程
上面介绍的方法仅仅是用户层面的一键退出,我们应该在所有Activity关闭后,紧接着再结束整个App的进程,实现真正的一键退出。
当然,上面说到了,如果使用BroadcastReceiver方法来关闭所有Activity,就无法再加接下来这一步了。
这里实现方法有两种,不过都非常简单,选择其中任意一种即可。
1 | //1.killProcess() |
这里你可能有个疑问,既然这里可以直接关闭App进程,那为什么还要第一步关闭所有Activity呢?
那我们就做一个实验,先逐个启动ActivityA,ActivityB和ActivityC,接着在ActivityC里调用结束App进程的方法。
我们会发现进程先结束了,接着又重新开启,启动ActivityA和ActivityB。
因为Android中的ActivityManager会时刻监听着进程,如果发现进程被非正常结束,它会去尝试重启这个进程。
总结
至此,一键退出App的所有方法你都应该掌握啦。在项目里根据实际情况,选择最适合的那一种吧。