1、結(jié)束進(jìn)程
- KillProcess():
可以殺死當(dāng)前應(yīng)用活動(dòng)的進(jìn)程,這一操作將會(huì)把所有該進(jìn)程內(nèi)的資源(包括線程全部清理掉)。當(dāng)然,由于ActivityManager時(shí)刻監(jiān)聽著進(jìn)程,一旦發(fā)現(xiàn)進(jìn)程被非正常Kill,它將會(huì)試圖去重啟這個(gè)進(jìn)程。
android.os.Process.killProcess(android.os.Process.myPid());
- System.exit():
Java中結(jié)束進(jìn)程的方法,調(diào)用它將關(guān)閉當(dāng)前的JVM虛擬機(jī)。
//正常退出
System.exit(0);
//非正常退出
System.exit(1);
KillProcess() 和 System.exit(),許多人都使用過,當(dāng)你棧里只有一個(gè)Activity的時(shí)候,這個(gè)措施是行之有效的。但當(dāng)關(guān)閉多個(gè)Activity的時(shí)候,棧里有多個(gè)Activity時(shí),這兩個(gè)方法就不起作用了。
因?yàn)橥ㄟ^殺進(jìn)程方式退出,會(huì)被系統(tǒng)認(rèn)為異常退出,會(huì)保存應(yīng)用的一些狀態(tài)信息比如Activity運(yùn)行棧,然后會(huì)恢復(fù)這個(gè)應(yīng)用。當(dāng)恢復(fù)一個(gè)Android應(yīng)用程序時(shí),會(huì)先從棧里面移除異常的Activity,相當(dāng)于Back鍵操作。
2、容器式
自定義一個(gè)Actiivty棧,通過單例模式的Activity棧來管理所有Activity,創(chuàng)建一個(gè)Activity管理類來實(shí)現(xiàn)
public class AppManager {
private Stack<WeakReference<Activity>> mActivityStack;
private static volatile AppManager mInstance;
private AppManager() {
}
public static AppManager getInstance() {
if (mInstance == null) {
synchronized (AppManager.class) {
if (mInstance == null) {
mInstance = new AppManager();
}
}
}
return mInstance;
}
/**
* 添加Activity到堆棧
* @param activity activity實(shí)例
*/
public void addActivity(Activity activity) {
if (mActivityStack == null) {
mActivityStack = new Stack<>();
}
mActivityStack.add(new WeakReference<>(activity));
}
/**
* 檢查弱引用是否釋放,若釋放,則從棧中清理掉該元素
*/
public void checkWeakReference() {
if (mActivityStack != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity temp = activityReference.get();
if (temp == null) {
it.remove();// 使用迭代器來進(jìn)行安全的加鎖操作
}
}
}
}
/**
* 獲取當(dāng)前Activity
* @return 當(dāng)前(棧頂)activity
*/
public Activity currentActivity() {
checkWeakReference();
if (mActivityStack != null && !mActivityStack.isEmpty()) {
return mActivityStack.lastElement().get();
}
return null;
}
/**
* 結(jié)束除當(dāng)前activtiy以外的所有activity
* @param activtiy 不需要結(jié)束的activity
*/
public void finishOtherActivity(Activity activtiy) {
if (mActivityStack != null && activtiy != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity temp = activityReference.get();
if (temp == null) {
// 清理掉已經(jīng)釋放的activity
it.remove();
continue;
}
if (temp != activtiy) {
// 使用迭代器來進(jìn)行安全的加鎖操作
it.remove();
temp.finish();
}
}
}
}
/**
* 結(jié)束除指定activtiy 集合以外的所有activity
* @param cls 指定的某類activity
*/
public void finishOtherActivity(Class<?> cls) {
if (mActivityStack != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity activity = activityReference.get();
if (activity == null) {
// 清理掉已經(jīng)釋放的activity
it.remove();
continue;
}
if (!activity.getClass().equals(cls)) {
// 使用迭代器來進(jìn)行安全的加鎖操作
it.remove();
activity.finish();
}
}
}
}
/**
* 結(jié)束當(dāng)前Activity
*/
public void finishActivity() {
Activity activity = currentActivity();
if (activity != null) {
finishActivity(activity);
}
}
/**
* 結(jié)束指定的Activity
* @param activity 指定的activity實(shí)例
*/
public void finishActivity(Activity activity) {
if (activity != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity temp = activityReference.get();
if (temp == null) {
// 清理掉已經(jīng)釋放的activity
it.remove();
continue;
}
if (temp == activity) {
it.remove();
}
}
activity.finish();
}
}
/**
* 結(jié)束指定類名的所有Activity
* @param cls 指定的類的class
*/
public void finishActivity(Class<?> cls) {
if (mActivityStack != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity activity = activityReference.get();
if (activity == null) {
// 清理掉已經(jīng)釋放的activity
it.remove();
continue;
}
if (activity.getClass().equals(cls)) {
it.remove();
activity.finish();
}
}
}
}
/**
* 結(jié)束所有Activity
*/
public void finishAllActivity() {
if (mActivityStack != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity activity = activityReference.get();
if (activity != null) {
activity.finish();
}
}
mActivityStack.clear();
}
}
/**
* 退出應(yīng)用程序
*/
public void exitApp() {
try {
finishAllActivity();
// 從操作系統(tǒng)中結(jié)束掉當(dāng)前程序的進(jìn)程
android.os.Process.killProcess(android.os.Process.myPid());
} catch (Exception e) {
Log.e("Exit exception", e.getMessage());
}
}
}
使用方式:
- 在BaseActivity#onCreate回調(diào)中添加AppManager.getInstance().addActivity(this)
- 獲取當(dāng)前棧頂activityAppManager.getInstance().currentActivity()
- 銷毀當(dāng)前activity:調(diào)用AppManager.getInstance().finishActivity()->可在BaseActivity#onDestroy添加
- 銷毀指定activity:調(diào)用AppManager.getInstance().finishActivity(XXX.class)
- 銷毀指定activity集合:調(diào)用AppManager.getInstance().finishActivity(Class<Activity> cls)
- 結(jié)束除當(dāng)前activtiy以外的所有activity:調(diào)用AppManager.getInstance().finishOtherActivity(XXX.class)
- 結(jié)束除當(dāng)前activtiy集合以外的所有activity:調(diào)用AppManager.getInstance().finishOtherActivity(Class<Activity> cls)
- 結(jié)束所有activity:調(diào)用finishAllActivity()
- 退出應(yīng)用調(diào)用AppManager.getInstance().exitApp()
在BaseActivity基類中添加引用,把所有Activity存儲(chǔ)起來,Activity銷毀的時(shí)候移除棧
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 添加Activity到堆棧
AppManager.getInstance().addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//移除當(dāng)前Activity
AppManager.getInstance().finishActivity(this);
}
}
如果activityStack持有Activity的強(qiáng)引用,當(dāng)某個(gè)Activity異常退出時(shí),activityStack沒有及時(shí)釋放掉引用,可能會(huì)導(dǎo)致內(nèi)存問題。
退回系統(tǒng)桌面,不退出應(yīng)用
Android應(yīng)用開發(fā)中,有一種場(chǎng)景,就是我們不希望用戶直接按Back鍵退出Activity,而是希望應(yīng)用隱藏到后臺(tái)的假退出,類似于按Home鍵的效果。
方法一:
public void onBackHome(Activity activity) {
if (activity != null) {
Intent home = new Intent(Intent.ACTION_MAIN);
home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
home.addCategory(Intent.CATEGORY_HOME);
activity.startActivity(home);
}
}
方法二:
public void onBackgroud(Activity activity, boolean isTaskRoot) {
if (activity != null) {
activity.moveTaskToBack(false);
}
}
moveTaskToBack()方法:在activity中調(diào)用 moveTaskToBack (boolean nonRoot)方法即可將activity 退到后臺(tái),不是finish()退出activity。
參數(shù)說明:
參數(shù)為false——代表只有當(dāng)前activity是task根,指應(yīng)用啟動(dòng)的第一個(gè)activity時(shí),才有效;
參數(shù)為true——?jiǎng)t忽略這個(gè)限制,任何activity都可以有效。
說明:判斷Activity是否是task根,Activity本身給出了相關(guān)方法:isTaskRoot()
moveTaskToBack調(diào)用后,task中activity的順序不會(huì)發(fā)生變化,例如A啟動(dòng)B,B中調(diào)用此方法退到后臺(tái),重新啟動(dòng)應(yīng)用會(huì)調(diào)用B中的onRestart-onStart-onResume方法,不會(huì)重新調(diào)用onCreate,而且在B中按下back鍵返回的還是A,這就是退到后臺(tái)的功能。類似于系統(tǒng)home鍵效果。
參考:
一招搞定Android Activity的管理
android常見技巧---Android按返回鍵退出程序但不銷毀