Android退出应用最优雅的方式
周sir |
2016年1月7日 |
Activity活动 |
0 条评论 | 1449
退出 Android 应用,常见做法是容器收齐 Activity、广播 finish,或直接杀进程。更稳的是把首页做成 singleTask,再配合退出广播。
一、容器式
建一个全局容器,把所有 Activity 存进去,退出时循环 finish:
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AtyContainer.getInstance().addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
AtyContainer.getInstance().removeActivity(this);
}
}
class AtyContainer {
private AtyContainer() {
}
private static AtyContainer instance = new AtyContainer();
private static List<Activity> activityStack = new ArrayList<Activity>();
public static AtyContainer getInstance() {
return instance;
}
public void addActivity(Activity aty) {
activityStack.add(aty);
}
public void removeActivity(Activity aty) {
activityStack.remove(aty);
}
public void finishAllActivity() {
for (int i = 0, size = activityStack.size(); i < size; i++) {
if (null != activityStack.get(i)) {
activityStack.get(i).finish();
}
}
activityStack.clear();
}
}
写法简单,但 activityStack 持有 Activity 的强引用。某个页面异常退出时如果没及时摘掉引用,就会拖成内存问题。
二、广播式
在 BaseActivity 里注册退出广播,退出时发一条,各页面自己 finish:
public class BaseActivity extends Activity {
private static final String EXITACTION = "action.exit";
private ExitReceiver exitReceiver = new ExitReceiver();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction(EXITACTION);
registerReceiver(exitReceiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(exitReceiver);
}
class ExitReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
BaseActivity.this.finish();
}
}
}
三、进程式
直接干掉当前进程,简单粗暴,也“有(wu)效”:
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
manager.killBackgroundProcesses(getPackageName());
三种都能退出,但模拟器上常弹出 Unfortunately, XXX has stopped;部分真机直接失效,只 finish 当前页(例如小米 Note 一类改过 fw 的 ROM,用这种方式要慎重)。
四、RS 优雅式
RS 即 Receiver + singleTask。Activity 四种启动模式里,singleTask 会在当前栈里找已有实例:找到就把它提到栈顶,并清掉它上面的页面。
打开 App 通常先 Splash,再 finish 掉 Splash 进主页。之后任意跳转,栈底永远是 HomeActivity。退出只需两步:
-
只在 HomeActivity 注册退出广播(不必每个页面都注册)。
-
把 HomeActivity 的启动模式设为
singleTask。
要退出时先 startActivity(this, HomeActivity.class),再发退出广播:栈里 HomeActivity 之上的页面被清掉,它自己接到广播后再 finish。没有弹框,不用跟机型 ROM 死磕,也没有容器式那份强引用包袱。
| 方式 |
做法 |
代价 |
| 容器式 |
List 收齐 Activity,循环 finish |
强引用,异常退出易泄漏 |
| 广播式 |
BaseActivity 注册,发 action.exit |
每个页面都要注册/反注册 |
| 进程式 |
killProcess / System.exit / killBackgroundProcesses |
模拟器弹框,部分真机失效 |
| RS 式 |
HomeActivity 设 singleTask + 退出广播 |
栈底必须是首页 |
原文出处:小鄧子(@Rx小鄧子)
一句话总结:别杀进程、别用 List 死攥 Activity;把 HomeActivity 设成 singleTask,再发一条退出广播,栈清干净、自己 finish,才是最稳的退法。
转载请注明来源:Android退出应用最优雅的方式
我是周sir,这是我的博客。致力于分享我学会的技术和优秀的文章。微信公众号 “周sir专栏” 欢迎大家关注。