-退出-
function exit_1:
Intent intent = new Intent(MainAct.this,StartAct.class);//跳轉(zhuǎn)到root activity
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//清除root activity之上的所有activity
intent.putExtra(StartAct.FLAG, StartAct.FLAG_EXIT);//帶過去一個(gè)標(biāo)志,在root activity中接收到這個(gè)標(biāo)志時(shí),就finish掉root activity
startActivity(intent);
function exit_2:
moveTaskToBack(boolean nonRoot);//當(dāng)nonRoot=flase時(shí),如果當(dāng)前activity不是root activity,則無任何效果
function exit_3:
finishAndRemoveTask();//從SDK21才有這個(gè)方法。
兩者異同:
都可以保留進(jìn)程。
exit_1,Task中沒有activity了,在recent task中會(huì)顯示黑屏截圖,再次啟動(dòng)應(yīng)用會(huì)從root activity開始啟動(dòng)。
exit_2,Task中保留activity,在recent task中會(huì)顯示棧頂activity截圖,再次啟動(dòng)應(yīng)用會(huì)把Task移到前臺(tái)。
從體驗(yàn)上來說,exit_2更好一點(diǎn),再次啟動(dòng)速度更快。但也意味著占用更多資源。不過支付寶、QQ什么的貌似都這么做。
-啟動(dòng)-
這里主要涉及到“初始化操作放在哪里”、“如何保存全局變量”、“APP在后臺(tái)被回收后再次啟動(dòng)”三個(gè)問題。
function launch_1:
初始化操作放在自定義Application的onCreate方法中。
這樣做帶來的問題是,隨著項(xiàng)目增長(zhǎng),引入的第三方庫越來越多,一般第三方庫都會(huì)要求在Application的onCreate方法中初始化,當(dāng)初始化操作比較耗時(shí)的時(shí)候,每次啟動(dòng)都會(huì)黑屏一段時(shí)間,這實(shí)際上是Application的onCreate方法正在執(zhí)行,root activity的onReusme還未執(zhí)行造成的。
為了減少黑屏?xí)r間,嘗試function launch_2:
放在root activity的onCreate方法中,所謂啟動(dòng)頁。一般來說,全局變量都由初始化操作賦值。全局變量保存在Application中,而初始化操作在root activity的onCreate方法中。當(dāng)用戶按HOME鍵或采用exit_2退出時(shí),Task會(huì)移動(dòng)到后臺(tái)。當(dāng)Task因內(nèi)存緊張而被系統(tǒng)回收時(shí),全局變量也被回收且沒有默認(rèn)的保存方法。
當(dāng)再次啟動(dòng)APP時(shí),注意這里有一個(gè)天坑?。?!
如果在Manifests文件中設(shè)置application標(biāo)簽
android:theme="@android:style/Theme.Translucent.XXXX"
那么會(huì)恢復(fù)重建原來所有的Activity,重建次序是從棧頂數(shù)第二個(gè)Activity到root activity,最后是棧頂?shù)腁ctivity。
如果設(shè)置
android:theme="@android:style/Theme.Black.XXXX"
那么會(huì)只重建原來?xiàng)m數(shù)腁ctivity,當(dāng)按下Back鍵,從棧頂數(shù)第二個(gè)Activity被推到棧頂,這個(gè)Activity才會(huì)重建。
也就是說,為了給全局變量重新賦值(不然就NullPoint了),必須設(shè)置成Translucent。
然后換一種思路,嘗試function launch_3:
當(dāng)Task在后臺(tái)被回收后,再次啟動(dòng)==重啟APP。
為了達(dá)到這一目的,需要這樣做:
設(shè)置一個(gè)標(biāo)志代表全局變量的狀態(tài),如果全局變量是未經(jīng)過初始化的,那么除了root activity外所有activity都不應(yīng)該被建立,如果系統(tǒng)想恢復(fù)它們,我們就主動(dòng)finish掉。最后Task中只剩root activity沒有被finish,正常執(zhí)行完onCreate后跳轉(zhuǎn)到新建的main activity??雌饋砭拖裰貑⒁粯?。
這樣做的問題是,finish只有等onCreate方法執(zhí)行完才會(huì)起作用,所以如果在onCreate方法中調(diào)用finish之后讀取全局變量,仍然會(huì)報(bào)NullPoint。另外,如果有用到Fragment,事情就變得異常復(fù)雜了。
嘗試持久化處理,function launch_4:
對(duì)全局變量持久化處理,或者在new的時(shí)候賦初始值。
這樣做的問題是:持久化處理會(huì)留下臟數(shù)據(jù);初始值不是異步更新的最新數(shù)據(jù)。
-額外的-
一些APP會(huì)通過設(shè)置Theme來提升體驗(yàn)。
設(shè)置android:theme="@android:style/Theme.Translucent.NoTitleBar",原來的黑屏變?yōu)橥该鳎?br> 設(shè)置android:theme="@android:style/Theme.Light.NoTitleBar",原來的黑屏變?yōu)榘灼粒?br> 他們的區(qū)別在初次啟動(dòng)時(shí)最容易觀察到,比如優(yōu)酷初次啟動(dòng)會(huì)在桌面卡2秒,就是第一種;知乎初次啟動(dòng)會(huì)白屏2秒,就是第二種;聯(lián)通客戶端初次啟動(dòng)會(huì)黑屏2秒,就是默認(rèn)的黑屏。
如果進(jìn)程中有一些服務(wù),那么服務(wù)啟動(dòng)的時(shí)候會(huì)執(zhí)行Application的onCreate。
//To do ……
alwaysRetainTaskState = true或flase沒有區(qū)別
網(wǎng)上說在root activity設(shè)置為false,被系統(tǒng)殺死后只保留root activity;設(shè)置為true,則保留全部activity。但是我試了試,在這方面沒有任何區(qū)別。
-Log- function launch_2 Translucent
----正常啟動(dòng)
Application--onCreate
root activity--onCreate
root activity--onStart
main activity--onCreate
main activity--onStart
secondary activity--onCreate
secondary activity--onStart
----Home鍵大約10s后
root activity--onStop
main activity--onStop
secondary activity--onStop
----360一鍵清理,或內(nèi)存不足而被回收
Process--DEAD
查詢Task信息,root activity、main activity、secondary activity都為DETROYED
----有守護(hù)進(jìn)程,自動(dòng)重啟
Application--onCreate
查詢Task信息,root activity、main activity、secondary activity仍為DETROYED
----再次啟動(dòng)APP
main activity--onCreate
main activity--onStart
root activity--onCreate
root activity--onStart
secondary activity--onCreate
secondary activity--onStart
secondary activity--onStop
secondary activity--onDestroy
為了secondary activity不destroy,可以在root activity加判斷:如果saveInstanceState != null則不跳轉(zhuǎn)到main activity。