前記
項(xiàng)目中用到了雙擊退出的功能隘冲,起初在Application中使用Stack在Activity基類(lèi)中的onCreate中把a(bǔ)ctivity壓入棧中贫贝,在onDestroy中把a(bǔ)ctivity彈出棧中,然后當(dāng)用戶要退出的時(shí)候再?gòu)棾鯯tack中的每一個(gè)Activity亏较,但使用LeakCanary檢測(cè)到嚴(yán)重的內(nèi)存泄漏,全是由于這個(gè)Stack持有了Activity的強(qiáng)引用,導(dǎo)致內(nèi)存無(wú)法釋放贯要,到最后就會(huì)拖垮應(yīng)用。
解決方案
由于android中的Activity在默認(rèn)加載模式下是一個(gè)棧結(jié)構(gòu)椭住,先進(jìn)后出崇渗,后進(jìn)先出,而要雙擊退出的地方只有主頁(yè)才需要京郑,所以代碼很簡(jiǎn)單宅广,重寫(xiě)主頁(yè)的onKeyDown就行了,代碼:
全局變量
private boolean isExit = false;//是否退出
private static final int EXIT_APP_INTERVAL = 2000;//退出程序時(shí)間間隔
onKeyDown代碼
攔截返回鍵點(diǎn)擊事件些举,返回true說(shuō)明事件消費(fèi)完畢跟狱,不再向上傳遞,因此不會(huì)結(jié)束Activity户魏,如果想結(jié)束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()代碼
按第一下時(shí)啟動(dòng)定時(shí)器驶臊,兩秒內(nèi)如果用戶沒(méi)有再點(diǎn)擊返回鍵則置全局變量isExit為false挪挤,如果用戶兩秒內(nèi)點(diǎn)擊了則說(shuō)明要結(jié)束應(yīng)用了,釋放所有資源关翎,結(jié)束本Activity扛门,執(zhí)行onDestroy銷(xiāo)毀進(jìn)程
/**
* 雙擊退出
*/
private boolean exitBy2Click() {
Timer tExit = null;
if (isExit == false) {
isExit = true; // 準(zhǔn)備退出
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秒鐘內(nèi)沒(méi)有按下返回鍵,則啟動(dòng)定時(shí)器取消掉剛才執(zhí)行的任務(wù)
return true;
} else {
//這里可以釋放app的資源(數(shù)據(jù)庫(kù)連接纵寝,下載任務(wù)等)
return false;
}
}
onDestroy
由于本Activity已經(jīng)是棧底Activity了论寨,執(zhí)行onDestroy說(shuō)明要退出應(yīng)用了,所以在這里可以殺死進(jìn)程
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
后記
網(wǎng)上的代碼爽茴,取之有道葬凳,前人的代碼不能瞎雞巴用。