生命周期
- onCreate( ): 表示Activity正在被創(chuàng)建些膨,這是生命周期的第一個(gè)方法,可以做一些初始化的工作屯蹦。
- onRestart( ): 表示Activity正在重新啟動(dòng)足画,Activity從不可見(jiàn)變?yōu)榭梢?jiàn)狀態(tài)時(shí),會(huì)被調(diào)用块促,比如點(diǎn)擊Home鍵又回到這個(gè)Activity時(shí)荣堰,就會(huì)調(diào)用onRestart( )。
- onStart( ): 表示Activity正在被啟動(dòng)竭翠,即將開(kāi)始振坚,這時(shí)Activity已經(jīng)可見(jiàn)了,但還沒(méi)出現(xiàn)在前臺(tái)斋扰,無(wú)法跟用戶交互渡八。
- onResume( ): 表示Activity已經(jīng)可見(jiàn)了,并且出現(xiàn)在前臺(tái)并開(kāi)始活動(dòng)了传货。
- onPause( ) : 表示Activity正在停止屎鳍,正常情況下,onStop緊接著被調(diào)用问裕,此時(shí)可以做一些存儲(chǔ)數(shù)據(jù)哥艇、狀態(tài)存儲(chǔ)等輕量級(jí)的存儲(chǔ)工作,在一些情況下僻澎,onPause方法或許是活動(dòng)觸發(fā)的最后的方法貌踏,因此開(kāi)發(fā)者需要在這個(gè)時(shí)候保存需要保存的信息十饥。
- onStop( ) : 表示Activity即將停止,如果內(nèi)存緊張祖乳,系統(tǒng)會(huì)直接結(jié)束這個(gè)活動(dòng)逗堵,而不會(huì)觸發(fā) onStop 方法。 所以保存狀態(tài)信息是應(yīng)該在onPause時(shí)做眷昆,而不是onStop時(shí)做蜒秤。
- onDestroy :當(dāng)Activity銷毀的時(shí)候,觸發(fā)該方法亚斋。和 onStop 方法一樣作媚,如果內(nèi)存緊張,系統(tǒng)會(huì)直接結(jié)束這個(gè)Activity而不會(huì)觸發(fā)該方法帅刊。我們可以在這里做一些回收工作和最終的資源釋放纸泡。
- onSaveInstanceState ():系統(tǒng)調(diào)用該方法,允許Activity保存之前的狀態(tài)赖瞒,比如說(shuō)在一串字符串中的光標(biāo)所處的位置等女揭。 通常情況下,開(kāi)發(fā)者不需要重寫(xiě)覆蓋該方法栏饮,在默認(rèn)的實(shí)現(xiàn)中吧兔,已經(jīng)提供了自動(dòng)保存活動(dòng)所涉及到的用戶界面組件的所有狀態(tài)信息。
幾種常見(jiàn)情況的生命周期調(diào)用流程:
1.針對(duì)一個(gè)特定的Activity袍嬉,第一次啟動(dòng)境蔼,回調(diào)是 onCreate -> onStart -> onResume.
2.當(dāng)打開(kāi)新的Activity或者切換到桌面時(shí): onPause -> onStop。
有一個(gè)特殊情況是當(dāng)新Activity是透明主題時(shí)伺通,那么當(dāng)前Activity不會(huì)回調(diào)onStop箍土。
3.當(dāng)用戶回到原Activity,且原Activity未被銷毀時(shí): onRestart -. onStart -> onResume .
4.當(dāng)用戶按下back鍵時(shí): onPause -> onStop -> onDestroy.
Activity之間的協(xié)調(diào)
當(dāng)一個(gè)activity啟動(dòng)另一個(gè)時(shí)泵殴,兩者都在走生命周期涮帘。如果這兩個(gè)activity之間要共享數(shù)據(jù),那么重點(diǎn)要理解當(dāng)?shù)诙€(gè)activity被創(chuàng)建時(shí)笑诅,第一個(gè)activity還沒(méi)有執(zhí)行到onStop()调缨。開(kāi)始新一個(gè)和結(jié)束前一個(gè)之間有交集。
當(dāng)activityA啟動(dòng)ActivityB時(shí)吆你,會(huì)按以下順序執(zhí)行:
1Activity A 的onPause()執(zhí)行弦叶。
2Activity B的onCreate(),onStart(),onResume()依次執(zhí)行(此時(shí)actvityB具有用戶焦點(diǎn))。
3Activity A的onStop()被執(zhí)行(假設(shè)A被B完全遮蓋)妇多。
你應(yīng)跟據(jù)這個(gè)順序來(lái)管理兩者之間的數(shù)據(jù)傳遞伤哺。比如,如果A要向數(shù)據(jù)庫(kù)中寫(xiě)入數(shù)據(jù),要保證B在初始化時(shí)能讀到A寫(xiě)入的完整數(shù)據(jù)立莉,那么A應(yīng)在onPause()方法中寫(xiě)入數(shù)據(jù)绢彤,而不能在onStop()中寫(xiě)入。
四種啟動(dòng)方式
任務(wù)棧的概念:
1.程序打開(kāi)時(shí)就創(chuàng)建了一個(gè)任務(wù)棧, 用于存儲(chǔ)當(dāng)前程序的activity,所有的activity屬于一個(gè)任務(wù)棧蜓耻。
2.一個(gè)任務(wù)棧包含了一個(gè)activity的集合, 去有序的選擇哪一個(gè)activity和用戶進(jìn)行交互:只有在任務(wù)棧棧頂?shù)腶ctivity才可以跟用戶進(jìn)行交互茫舶。
3.任務(wù)棧可以移動(dòng)到后臺(tái), 并且保留了每一個(gè)activity的狀態(tài). 并且有序的給用戶列出它們的任務(wù), 而且還不丟失它們狀態(tài)信息刹淌。
4.退出應(yīng)用程序時(shí):當(dāng)把所有的任務(wù)棧中所有的activity清除出棧時(shí),任務(wù)棧會(huì)被銷毀,程序退出饶氏。
任務(wù)棧的缺點(diǎn):
1.每開(kāi)啟一次頁(yè)面都會(huì)在任務(wù)棧中添加一個(gè)Activity,而只有任務(wù)棧中的Activity全部清除出棧時(shí),任務(wù)棧被銷毀有勾,程序才會(huì)退出,這樣就造成了用疹启,戶體驗(yàn)差, 需要點(diǎn)擊多次返回才可以把程序退出了。
2.每開(kāi)啟一次頁(yè)面都會(huì)在任務(wù)棧中添加一個(gè)Activity還會(huì)造成數(shù)據(jù)冗余, 重復(fù)數(shù)據(jù)太多, 會(huì)導(dǎo)致內(nèi)存溢出的問(wèn)題(OOM)蔼卡。
因此喊崖,我們引入了啟動(dòng)模式來(lái)修改系統(tǒng)的默認(rèn)行為:
<activity android:name=".MainActivity" android:launchMode="standard" />
其中的launchMode有四種方式:
1.singleTask:標(biāo)準(zhǔn)模式,每次啟動(dòng)一個(gè)Activity 都會(huì)重新創(chuàng)建一個(gè)新的實(shí)例菲宴,不管這個(gè)實(shí)例是否已經(jīng)存在贷祈。
2.singleTop: 棧頂復(fù)用模式趋急,如果新Activity 已經(jīng)位于任務(wù)棧的棧頂喝峦,那么此Activity不會(huì)被重新創(chuàng)建,同時(shí)它的onNewIntent方法會(huì)被回調(diào)呜达,通過(guò)此方法的參數(shù)谣蠢,我們可以取出當(dāng)前請(qǐng)求的信息。
3.singleTask: 棧內(nèi)復(fù)用模式查近,只要Activity在一個(gè)棧中存在眉踱,那么多次啟動(dòng)都不會(huì)重新創(chuàng)建實(shí)例,當(dāng)需要運(yùn)行的Activity不在棧頂時(shí)霜威,系統(tǒng)會(huì)清空目標(biāo)Activity上面的其他Activity(clearTop),使目標(biāo)Activity實(shí)例成為棧頂谈喳。
**4.singleInstance **:?jiǎn)螌?shí)例模式,在這種加載模式下戈泼,系統(tǒng)保證只會(huì)創(chuàng)建一個(gè)目標(biāo)Activity實(shí)例婿禽,并會(huì)使用一個(gè)全新的Task棧來(lái)加載該Activity實(shí)例。采用singleInstance模式加載的activity所在的Task只包含該Activity.
使用場(chǎng)景
singleTop適合接收通知啟動(dòng)的內(nèi)容顯示頁(yè)面大猛。例如扭倾,某個(gè)新聞客戶端的新聞內(nèi)容頁(yè)面,如果收到10個(gè)新聞推送挽绩,每次都打開(kāi)一個(gè)新聞內(nèi)容頁(yè)面是很煩人的膛壹。
singleTask適合作為程序入口點(diǎn)。例如瀏覽器的主界面。不管從多少個(gè)應(yīng)用啟動(dòng)瀏覽器模聋,只會(huì)啟動(dòng)主界面一次肩民,其余情況都會(huì)走onNewIntent,并且會(huì)清空主界面上面的其他頁(yè)面链方。之前打開(kāi)過(guò)的頁(yè)面此改,打開(kāi)之前的頁(yè)面就ok,不再新建侄柔。
singleInstance適合需要與程序分離開(kāi)的頁(yè)面共啃。例如鬧鈴提醒,將鬧鈴提醒與鬧鈴設(shè)置分離暂题。singleInstance不要用于中間頁(yè)面移剪,如果用于中間頁(yè)面,跳轉(zhuǎn)會(huì)有問(wèn)題薪者,比如:A -> B (singleInstance) -> C纵苛,完全退出后,在此啟動(dòng)言津,首先打開(kāi)的是B攻人。
另外,stackflow的一位大神也總結(jié)得很好:
Between the Browser and Alarm Clock applications, you cover all four launch modes:
1.BrowserActivity uses singleTask. There is only one browser activity at a time and it doesn't become part tasks that send it intents to open web pages. While it might return to whatever most recently launched it when you hit back it is actually fixed at the bottom of its own task activity stack. It will share its task with activities that it launches like bookmarks.
2.BrowserBookmarksPage uses singleTop. While there can be multiple instances of this activity, if there is already one at the top of the task's activity stack it will be reused and onNewIntent() will be called. This way you only have to hit back once to return to the browser if the bookmarks activity is started multiple times.
3.AlarmClock uses standard. The user can launch multiple instances of this activity and these instances can be part of any task and anywhere in the activity stack. As a fairly simple application it doesn't really demand tight control of its activity.
4.AlarmAlert uses singleInstance. Only one alert activity at a time and it is always its own task. Anything it launches (if anything) becomes part of its own new task.
啟動(dòng)一個(gè)Activity
你可以用startActivity()啟動(dòng)一個(gè)activity悬槽,它有一個(gè)參數(shù)是intent怀吻,你需要在這個(gè)intent中指明要調(diào)用的activity。Intent中你可以明確地指定要啟動(dòng)的activity初婆,或只指定activity的類型蓬坡,此時(shí)系統(tǒng)會(huì)為你挑選一個(gè)合適的activity,這個(gè)activity可能位于其它程序中磅叛,也可能位于你自己的程序中屑咳。Intent的putextra方法中可以帶一些被新activity使用的數(shù)據(jù)(相當(dāng)于參數(shù)傳遞)。然后在新Activity中調(diào)用getIntent方法獲取Intent實(shí)例弊琴,并得到里面的數(shù)據(jù)兆龙。
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
** Activity的關(guān)閉**:Activity可以內(nèi)部調(diào)用finish()方法關(guān)閉它自己,也可以調(diào)用finishActivity()方法關(guān)閉其它的activity敲董。