前记
项目中用到了双击退出的功能,起初在Application中使用Stack在Activity基类中的onCreate中把activity压入栈中,在onDestroy中把activity弹出栈中,然后当用户要退出的时候再弹出Stack中的每一个Activity,但使用LeakCanary检测到严重的内存泄漏,全是由于这个Stack持有了Activity的强引用,导致内存无法释放,到最后就会拖垮应用。
解决方案
由于android中的Activity在默认加载模式下是一个栈结构,先进后出,后进先出,而要双击退出的地方只有主页才需要,所以代码很简单,重写主页的onKeyDown就行了,代码:
全局变量
private boolean isExit = false;//是否退出
private static final int EXIT_APP_INTERVAL = 2000;//退出程序时间间隔
onKeyDown代码
拦截返回键点击事件,返回true说明事件消费完毕,不再向上传递,因此不会结束Activity,如果想结束Activity直接return super.onKeyDown(keyCode,event)就行
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
boolean flag = exitBy2Click() ? true : super.onKeyDown(keyCode, event);
return flag;
}
return super.onKeyDown(keyCode, event);
}
exitBy2Click()代码
按第一下时启动定时器,两秒内如果用户没有再点击返回键则置全局变量isExit为false,如果用户两秒内点击了则说明要结束应用了,释放所有资源,结束本Activity,执行onDestroy销毁进程
/**
* 双击退出
*/
private boolean exitBy2Click() {
Timer tExit = null;
if (isExit == false) {
isExit = true; // 准备退出
Toast.makeText(MainActivity.this, R.string.toast_double_click_exit, Toast.LENGTH_SHORT).show();
tExit = new Timer();
tExit.schedule(new TimerTask() {
@Override
public void run() {
isExit = false; // 取消退出
}
}, EXIT_APP_INTERVAL); // 如果2秒钟内没有按下返回键,则启动定时器取消掉刚才执行的任务
return true;
} else {
//这里可以释放app的资源(数据库连接,下载任务等)
return false;
}
}
onDestroy
由于本Activity已经是栈底Activity了,执行onDestroy说明要退出应用了,所以在这里可以杀死进程
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
后记
网上的代码,取之有道,前人的代码不能瞎鸡巴用。
网友评论