Android 退出應(yīng)用程序和返回桌面

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按返回鍵退出程序但不銷毀

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容