Android基礎(chǔ)之一鍵退出App

首先需要知道,一鍵退出app要實(shí)現(xiàn)兩個(gè)結(jié)果;

1.Activity退出

2.進(jìn)程結(jié)束

我們先看"Activity的退出",大概有以下幾種方法可以實(shí)現(xiàn)Activity的退出.

方法1:使用BroadcastReceiver.

?????? 1.1寫一個(gè)類集成BroadCastReceiver,重寫onReceiver方法,方法里面調(diào)用finish方法

?????? 1.2 在每一個(gè)activity里面注冊(cè)廣播,并且在Actviity銷毀的時(shí)候取消注冊(cè)廣播.

???? 1.3 在需要退出app的地方,發(fā)送廣播即可.

優(yōu)點(diǎn):應(yīng)用場景廣泛:兼顧單 / 多任務(wù)棧 & 多啟動(dòng)模式的情況

缺點(diǎn): 需要在每個(gè) Activity 里注冊(cè)廣播接收器

方法2:利用Activity的啟動(dòng)模式,singleTask模式

singletask模式:單一任務(wù)模式,若該Activity實(shí)例在棧中存在,那么將會(huì)將其他Activity實(shí)例從棧中移除.,.

???? 2.1 將 App的入口 Activity 設(shè)置成 SingleTask 啟動(dòng)模式

???? 2.2 在入口 Activity重寫 onNewIntent(),根據(jù)傳來的標(biāo)志決定是否退出;

????????????????????????? @Override

?????????????????? protected void onNewIntent(Intent intent) {

??????????????????????????? super.onNewIntent(intent);

?????????????????????????????? if (intent != null) {

??????????????????????????? // 是否退出App的標(biāo)識(shí)

???????????????????????????? boolean isExitApp = intent.getBooleanExtra("exit", false);

?????????????????????????????? if (isExitApp) {

????????????????????????? // 關(guān)閉自身

??????????????????????????? this.finish();

??????????? ? ? ?? }

???? ? ?? ?? }

???? }

?? 2.3 在需要退出時(shí)調(diào)用 exitApp()

??????????????????? private void exitApp() {

?????????????????? Intent intent = new Intent(context, MainActivity.class);

?????????????????????? intent.putExtra("exit", true);

???????????????????? context.startActivity(intent);

??????????????????????? // 結(jié)束進(jìn)程

?????????????????????? // System.exit(0);

}

???? ? ? ? ? ? ?? 優(yōu)點(diǎn): 使用簡單 & 方便

????????? ? ? ? ? 缺點(diǎn): 規(guī)定 App的入口Activity采用SingleTask啟動(dòng)模式

????????????????? 使用范圍局限:只能結(jié)束當(dāng)前任務(wù)棧的Activity,若出現(xiàn)多任務(wù)棧(即采用SingleInstance啟動(dòng)模式)則無法處理

??????? ? ? 應(yīng)用場景

???????????? Activity單任務(wù)棧

方法三: 利用Activity啟動(dòng)標(biāo)記位

Intent.FLAG_ACTIVITY_CLEAR_TOP:銷毀目標(biāo)Activity和它之上的所有Activity,重新創(chuàng)建目標(biāo)Activity

Intent.FLAG_ACTIVITY_SINGLE_TOP:若啟動(dòng)的Activity位于任務(wù)棧棧頂,那么此Activity的實(shí)例就不會(huì)重建,而是重用棧頂?shù)膶?shí)例( 調(diào)用onNewIntent())

?? 3.1:在MainActivity 中設(shè)置 重寫 onNewIntent()

? 3.2在需要退出的地方啟動(dòng)Macitivty并且設(shè)置標(biāo)記位.

Intent intent = new Intent();

intent.setClass(Activity2.this, MainActivity.class);

// 設(shè)置標(biāo)記位

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

// 步驟1:該標(biāo)記位作用:銷毀目標(biāo)Activity和它之上的所有Activity,重新創(chuàng)建目標(biāo)Activity

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

// 步驟2:若啟動(dòng)的Activity位于任務(wù)棧棧頂,那么此Activity的實(shí)例就不會(huì)重建,而是重用棧頂?shù)膶?shí)例( 調(diào)用實(shí)例的 onNewIntent() )

// 在步驟1中:MainActivity的上層的Activity2會(huì)被銷毀,此時(shí)MainActivity位于棧頂;由于步驟2的設(shè)置,所以不會(huì)新建MainActivity而是重用棧頂?shù)膶?shí)例&調(diào)用實(shí)onNewIntent()

// 傳入自己設(shè)置的退出App標(biāo)識(shí)

intent.putExtra("exit", true);

startActivity(intent);

優(yōu)點(diǎn):使用簡單

缺點(diǎn):只能結(jié)束當(dāng)前任務(wù)棧的actvitiy,若出現(xiàn)多任務(wù)棧則無法處理.

方法四:通過系統(tǒng)任務(wù)棧

通過 ActivityManager 獲取當(dāng)前系統(tǒng)的任務(wù)棧 & 把棧內(nèi)所有Activity逐個(gè)退出.

// 1. 通過Context獲取ActivityManager

ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);

// 2. 通過ActivityManager獲取任務(wù)棧

List appTaskList = activityManager.getAppTasks();

// 3. 逐個(gè)關(guān)閉Activity

for (ActivityManager.AppTask appTask : appTaskList) {

appTask.finishAndRemoveTask();

}

// 4. 結(jié)束進(jìn)程

// System.exit(0);

缺點(diǎn):只能結(jié)束當(dāng)前activity的任務(wù)棧,若有多個(gè)任務(wù)棧,則無法退出.

優(yōu)點(diǎn):使用簡單.

方法五:通過記錄保存activity實(shí)例

通過在Application子類中建立一個(gè) Activity鏈表:保存正在運(yùn)行的Activity實(shí)例;當(dāng)需要一鍵退出App時(shí)把鏈表內(nèi)所有Activity實(shí)例逐個(gè)退出即可(其實(shí)我個(gè)人認(rèn)為使用list集合也可以)

5.1:在BaseApplication類的子類里建立Activity鏈表

public class Carson_BaseApplicaiton extends Application {

// 此處采用 LinkedList作為容器,增刪速度快

public static LinkedList activityLinkedList;

@Override

public void onCreate() {

super.onCreate();

activityLinkedList = new LinkedList<>();

registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {

@Override

public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

Log.d(TAG, "onActivityCreated: " + activity.getLocalClassName());

activityLinkedList.add(activity);

// 在Activity啟動(dòng)時(shí)(onCreate()) 寫入Activity實(shí)例到容器內(nèi)

}

@Override

public void onActivityDestroyed(Activity activity) {

Log.d(TAG, "onActivityDestroyed: " + activity.getLocalClassName());

activityLinkedList.remove(activity);

// 在Activity結(jié)束時(shí)(Destroyed()) 寫出Activity實(shí)例

}

@Override

public void onActivityStarted(Activity activity) {

}

@Override

public void onActivityResumed(Activity activity) {

}

@Override

public void onActivityPaused(Activity activity) {

}

@Override

public void onActivityStopped(Activity activity) {

}

@Override

public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

}

});

}

public ?void exitApp() {

Log.d(TAG, "容器內(nèi)的Activity列表如下 ");

// 先打印當(dāng)前容器內(nèi)的Activity列表

for (Activity activity : activityLinkedList) {

Log.d(TAG, activity.getLocalClassName());

}

Log.d(TAG, "正逐步退出容器內(nèi)所有Activity");

// 逐個(gè)退出Activity

for (Activity activity : activityLinkedList) {

activity.finish();

}

// ?結(jié)束進(jìn)程

// System.exit(0);

}

}

// 記得在Manifest.xml中添加

android:name=".Carson_BaseApplicaiton"

....

步驟2:需要一鍵退出 App 時(shí),獲取該 Applicaiton類對(duì)象 & 調(diào)用exitApp()

private Carson_BaseApplicaiton app;

app = (Carson_BaseApplicaiton)getApplication();

app.exitApp();

優(yōu)點(diǎn):

缺點(diǎn): 兼顧單 / 多任務(wù)棧 & 多啟動(dòng)模式的情況

缺點(diǎn): 需要 Activity 經(jīng)歷正常的生命周期,即創(chuàng)建時(shí)調(diào)用onCreate(),結(jié)束時(shí)調(diào)用onDestroy()

方法六,使用RxBus,在每一個(gè)Activity里面訂閱,退出發(fā)送事件請(qǐng)求.

優(yōu)點(diǎn): 使用簡單

缺點(diǎn): 實(shí)現(xiàn)復(fù)雜:RxBus 本身的實(shí)現(xiàn)難度 & 需要在每個(gè)Activity注冊(cè)和取消訂閱 RxBus 使用






上述都只是完成了第一步,下面看如何結(jié)束進(jìn)程

// 方式1:android.os.Process.killProcess()

android.os.Process.killProcess(android.os.Process.myPid()) ;

// 方式2:System.exit()

// System.exit() = Java中結(jié)束進(jìn)程的方法:關(guān)閉當(dāng)前JVM虛擬機(jī)

System.exit(0);

// System.exit(0)和System.exit(1)的區(qū)別

// 1. System.exit(0):正常退出;

// 2. System.exit(1):非正常退出,通常這種退出方式應(yīng)該放在catch塊中。

Android中的ActivityManager時(shí)刻監(jiān)聽著進(jìn)程*。一旦發(fā)現(xiàn)進(jìn)程被非正常結(jié)束,它將會(huì)試圖去重啟這個(gè)進(jìn)程。

本文參考鏈接

https://mp.weixin.qq.com/s?__biz=MzI3MTEzMDI2MA==&mid=2654089109&idx=1&sn=1d979c74c8330e9e239efc42fb788719&chksm=f100046ec6778d78115b33fb439baf7f12ede9d08dc1e21d48d53bfaf20c39ef03ad58fea7d6&mpshare=1&scene=23&srcid=1117zY9fc7ObIdtaH41oMVxL#rd

?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,317評(píng)論 0 17
  • 哎呀呀 ,馬上就要面臨找工作了,媛媛心里緊張呀. 作為一個(gè)即將畢業(yè)的Android程序媛,開始面臨找工作了,...
    左神話閱讀 5,154評(píng)論 7 59
  • 最近剛從舊公司離職,為面試在做準(zhǔn)備,因?yàn)槠綍r(shí)開發(fā)CV大法用得比較多,很多基礎(chǔ)知識(shí)掌握得不是很牢靠以及很多工具框架只...
    黎清海閱讀 2,327評(píng)論 1 19
  • 1.什么是Activity?問的不太多,說點(diǎn)有深度的 四大組件之一,一般的,一個(gè)用戶交互界面對(duì)應(yīng)一個(gè)activit...
    JoonyLee閱讀 5,855評(píng)論 2 51
  • 生或者死,是每天都要思考的問題 除此之外,還有想你
    閑莊聽水閱讀 170評(píng)論 2 1

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