该文章参考了Carson_Ho(https://juejin.im/post/5a4ae66d518825390e348aac)博主的文章,如有侵权请通知删除
在安卓面试过程中经常会被问到如何从一个Activity中退出整个App的问题,下面我就总结一下如何回答该问题。
重点:退出整个App有两个步骤,第一步骤是关闭所有的Activity,第二步骤是退出这个App进程。
第一种:创建存放所有Activity的集合进行遍历退出
1.写一个基类BaseActivity,让你所创建的Activity都继承与它,在该基类中定义一个LinkedList(因为
应用场景是增删次数多,所以此处用链表),在每个onCreate方法中将自身的Activity添加add进该链
表中,其次在每个onDestory中再删除remove自身的Activity即可,然后再BaseActivity中些一个清空删
除所有Activity并退出进程的方法,当你想退出整个App的时候调用这个方法即可。
2.写一个Application的子类让它在onActivityCreated方法中添加每一个activity到链表中,然后在其中
写一个退出App的方法,当想退出的时候,调用该方法即可,记得在Manifest文件中添加这个
application。
优点:应用场景广泛:兼顾单 / 多任务栈 & 多启动模式的情况
缺点:需要 Activity 经历正常的生命周期,即创建时调用onCreate(),结束时调用onDestroy()
因为只有这样经历正常的生命周期才能将 Activity正确写入 & 写出 容器内
应用场景:任意情况下的一键退出 App 实现
第二种:RxBus
使用 RxBus当作事件总线,在每个 Activity里注册RxBus订阅(响应动作 = 关闭自身);当需要退出
App时 发送退出事件请求即可。
优点:可与 RxJava & RxBus 相结合
缺点:实现复杂:RxBus 本身的实现难度 & 需要在每个Activity注册和取消订阅 RxBus 使用
应用场景:需要与RxJava 结合使用时
若项目中没有用到RxJava & RxBus 不建议使用
注:上述方法仅仅只是结束当前App所有的Activity (在用户的角度确实是退出了 App),但实际上该App的进程还未结束
第三种:通过 Android 组件: BroadcastReceiver
在每个 Activity 里注册广播接收器(响应动作 = 关闭自身);当需要退出 App 时 发送广播请求即可
优点:应用场景广泛:兼顾单 / 多任务栈 & 多启动模式的情况
缺点:实现复杂:需要在每个 Activity 里注册广播接收器
应用场景:任意情况下的一键退出 App,但无法终止 App 进程
第四种:通过Activity的SingleTask启动模式
在Manifest文件中修改Activity启动模式,记住栈底的那个Activity,在Activity中重写onNewIntent方
法,里面增加一个退出整个App的标识符判断,再写一个退出App的方法,然后想退出的时候将
Activity跳转到栈底的那个Activity然后创建并启动退出App的意图,然后结束进程即可。
优点:使用简单 & 方便
缺点:规定 App的入口Activity采用SingleTask启动模式
使用范围局限:只能结束当前任务栈的Activity,若出现多任务栈(即采用SingleInstance启动模式)
则无法处理
应用场景:Activity单任务栈
第五种:通过Activity的两个flag标识符
原理:对入口Activity采用 2 标记位:
Intent.FLAG_ACTIVITY_CLEAR_TOP:销毁目标Activity和它之上的所有Activity,重新创建目标Activity
Intent.FLAG_ACTIVITY_SINGLE_TOP:若启动的Activity位于任务栈栈顶,那么此Activity的实例就不会重建,而是重用栈顶的实例( 调用onNewIntent())
记住栈底的那个Activity,在Activity中重写onNewIntent方法,里面增加一个退出整个App的标识符判
断,当想退出App的时候,创建一个Intent,并且set上面两个flag,其次再put一个退出整个App的标识
符即可。
优点 使用简单 & 方便
缺点:使用范围局限:只能结束当前任务栈的Activity,若出现多任务栈(即采用SingleInstance启动
模式)则无法处理
应用场景:Activity单任务栈
第六种:通过系统任务栈
通过 ActivityManager 获取当前系统的任务栈 & 把栈内所有Activity逐个退出,然后退出进程。
优点:使用简单、方便
缺点:使用范围局限:只能结束当前任务栈的Activity,若出现多任务栈(即采用SingleInstanc启动模
式)则无法处理
对 Android 版本要求较高:Android 5.0以上
应用场景:Android 5.0以上的 Activity单任务栈
至于退出进程的话,有两种方法
// 方式1:android.os.Process.killProcess()
android.os.Process.killProcess(android.os.Process.myPid()) ;
// 方式2:System.exit()
// System.exit() = Java中结束进程的方法:关闭当前JVM虚拟机
System.exit(0);
// System.exit(0)和System.exit(1)的区别
// 1. System.exit(0):正常退出;
// 2. System.exit(1):非正常退出,通常这种退出方式应该放在catch块中。
特别注意
假设场景:当前 Activity ≠ 当前任务栈最后1个Activity时,调用上述两个方法会出现什么情况呢?(即Activity1 - Activity2 -Activity3(在Activity3调用上述两个方法))
答:
结束Activity3(当前 Activity )& 结束进程
再次重新开启进程 & 启动 Activity1 、 Activity2
即在Android 中,调用上述Dalvik VM本地方法结果是:
1.结束当前 Activity & 结束进程
2.之后再重新开启进程 & 启动 之前除当前 Activity 外的已启动的 Activity
原因:** Android中的ActivityManager时刻监听着进程**。一旦发现进程被非正常结束,它将会试图去重启这个进程。
应用场景
当任务栈只剩下当前Activity(即退出了其余 Activity后),调用即可退出该进程,即在(步骤1)结束当前 App 所有的 Activity 后,调用该方法即可一键退出App(更多体现在结束进程上)
注: 与 “在最后一个Activity调用 finish()”的区别:finish()不会结束进程,而上述两个方法会
至此所有方法差不多已经完成了,如果要具体查看每种方法的实例,请查看最上方给出的原博主地址(内附Demo)。