Activity知識點整理 [復制鏈接]

2018-11-22 10:42
shareiOS 閱讀:508 評論:0 贊:0
Tag:  
Activity的知識點主要有:
生命周期(正常與異常);
啟動模式(Launcher Mode);
隱式啟動(IntentFilter與action、category、data);
一、Activity的生命周期:
1. 正常的生命周期(七個方法):
先附上正常的生命周期流程:



正常情況下,一個Activity所經歷的生命周期是:onCreate()->onStart()->onResume()->onPause()->onStop()->onDestory();除此之外,還有一個onRestart(),這個將在后面講到;
onCreate():當Activity第一次創建的時候會被調用(注意:一個Activity是不能被new出來的,因為Activity是基于組件的設計模式,需要在Android工程環境中才能正常地運行,此時有一個核心的功能類Context);在onCreate()這個方法中,我們可以做一些初始化工作,比如:調用setContentView()去加載界面布局資源(但是此時只是加界面布局資源addView到DecorView中,并不是真正地繪制布局,真正繪制是在onResume的時候),初始化Activity所需要的數據;當然onCreate()方法中參數有一個Bundle對象,可以用來恢復異常情況下Activity結束時的狀態(此時涉及到Activity的異常生命周期);
onStart():表示Activity正在被啟動,即將開始,這是Activity已經出現,但是還沒有出現在前臺(處于后臺),無法與用戶交互;此時我們可以理解為此時的Activity已經顯示出來,但是我們還是看不到;
onResume():表示Activity已經可見,并且出現在前臺并開始活動;需要和onStart()對比,onStart()的時候Activity還在后臺,onResume()的時候Activity才顯示到前臺,布局資源的繪制是在onResume()的時候才開始繪制的;
onPause():表示Activity正在停止(暫停),但是仍可見,正常情況下,onStop會被調用;但在特殊情況下(比如:在singleTop啟動模式下啟動棧頂的Activity的時候,會調用onNewIntent()),如果這個時候快速地回到當前的Activity,那么Activity的onResume就會被調用;在onPause中不能執行耗時操作,因為會影響到新的Activity的啟動;因為onPause執行完,新的Activity的onResume才會執行;可以做一些重要數據的輕量型保存;
onStop():表示Activity即將停止,不可見,位于后臺;可以做稍微重量級的回收工作,但是不能太耗時;
onDestroy():表示Activity即將銷毀,這是Activity生命周期的最后一個回調,可以做一些資源的回收,比如:gc回收工作等等;
onReStart():表示Activity正在重新啟動,一般情況下,當當前的Activity從不可見變為可見的時候,onRestart就會被調用,這種情形一般是由用戶導致的,比如:當我們按Home鍵回到主界面的時候,或者打開一個Activity后,按back健返回之前的Activity(都是onPause()->onStop()->onRestart()->onStart()->onResume());
生命周期的幾種情況:
第一次啟動Activity時:onCreate()->onStart()->onResume();
用戶打開新的Activity時:(舊)onPause() -> (新)onCreate() -> (新)onStart() -> (新)onResume() -> (舊)onStop();
再次回到舊Activity時(按下back健):(新)onPause() -> (舊)onRestart() -> (舊)onStart() -> (舊)onResume() -> (新)onStop() -> (新)onDestory();
按下back健:onPause() -> onStop() -> onDestory();
按下Home健回到主界面,再次返回到該Activity的時候:onPause() -> onStop() -> onRestart() -> onStart() -> onResume();
調用finish()方法時:onPause() -> onStop() -> onDestory();
當Activity彈出一個普通的Dialog時:onResume()
當Activity彈出一個Activity樣式的Dialog時:onResume() -> onPause();當該Dialog退出后:onPause() -> onResume();
當啟動一個透明的Activity的時候:(舊)onPause() -> (新)onCreate() -> (新)onStart() -> (新)onResume(); 當此時按下back健時:(新)onPause() -> (舊)onResume() -> (新)onStop() -> (新)onDestory();
2. 特殊情況下的生命周期:
上面介紹了正常情況下的生命周期,接下來介紹一下特殊情況下的生命周期,主要有兩種特殊的生命周期:1. 橫豎屏切換;2. 資源內存不足導致優先級低的Activity被殺死;

1. 橫豎屏切換
在橫豎屏切換過程中,會發生Activity被銷毀并重建的過程;
特殊情況下的生命周期會涉及到這個回調:onSaveInstanceState()、onRestoreInstanceState();

onSaveInstanceState:在Activity由于異常情況下終止時,系統會調用onSaveInstanceState()來保存當前的Activity的狀態,這個方法是在onStop之前調用的,在onPause前后要看情況(橫豎屏切換時,該方法在onPause之后,在onStop之前),并且把Activity銷毀時onSaveInstanceState方法所保存的Bundle對象參數傳遞給onRestoreInstanceState和onCreate方法;

onRestoreInstanceState:因此,可以通過onRestoreInstanceState來恢復Activity的狀態,該方法的調用是在onStart之后;其中onCreate和onRestoreInstanceState方法來恢復Activity是有區別的:onRestoreInstanceState回調則表明該Bundle對象一定是非空的;而onCreate需要進行判斷是否為空;一般建議使用onRestoreInstanceState;

橫豎屏切換時: (舊)onResume() -> (舊)onPause() -> (舊)onSaveInstanceState() -> (舊)onStop() -> (舊)onDestory() -> (新)onCreate() -> (新)onStart() -> (新)onRestoreInstanceState() -> (新)onResume() ;



如果想避免橫豎屏切換時,Activity的銷毀和重建,我們可以在AndroidManifest中設定Activity的configChanges屬性:
android:configChanges = "orientation| screenSize"

回調了onConfigurationChanged方法:

@Override
public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

2. 當資源不足的時候導致優先級低的Activity被殺死:
Activity的優先級可以劃分為: 
1. 前臺Activity——正在與用戶交互的Activity,優先級最高; 
2. 可見但非前臺Activity——比如彈出一個對話框,此時的Activity處于后臺但是可見,無法與用戶進行交互; 
3. 后臺Activity——已經被停止的Activity,比如執行了onStop,優先級最低;

Activity的三種運行狀態:
Resumed(活動狀態):此時的Activity正在屏幕上顯示,并且可以與用戶進行交互;
Paused(暫停狀態):比較不常見的狀態,此時Activity是可見的,但并不是處于前臺的;比如:一個非全屏或者透明的Activity是Resumed的時候,沒有完全遮蓋這個Activity;
Stopped(停止狀態):當Activity完全不可見時,此時的Activity處于后臺,仍在內存中保留著狀態,并沒有銷毀;比如:當我啟動一個新的Activity的時候,之前的Activity處于后臺,當我們按下Back鍵的時候,之前的Activity就會恢復原來的狀態;
二、啟動模式(Launcher Mode):
Android提供了四種啟動方式: 
1.standard 標準模式; 
2.singleTop 棧頂復用模式; 
3.singleTask 棧內復用模式; 
4.singleInstance 單例模式;

啟動模式的數據結構——棧:

Activity的管理是采用任務棧的形式,任務棧采用“后進先出” 的棧結構;



Activity的LauncherMode:
1.標準模式(standard):每次啟動一個Activity的時候,都會創建一個新的Activity的實例并置于棧頂;誰啟動了這個新的Activity,該Activity就會處于那個Activity所處的棧中;



特殊情況下:如果Service或者Application啟動一個Activity的時候,此時并沒有所謂的任務棧,為了解決這個問題,我們可以為待啟動的Activity指定一個FLAG_ACTIVITY_NEW_TASK標記位,創建一個任務棧;
2.棧頂復用模式(singleTop):如果新建的Activity位于任務棧的棧頂,此時Activity就不需要被創建,而是復用棧頂的Activity,回調onNewIntent方法;如果該Activity不處于棧頂,則會創建該Activity的新實例,置于棧頂;

應用場景:在通知欄點擊通知的時候,啟動Activity,此時使用singleTop模式,可以避免多次點擊,創建多個Activity;
3.棧內復用模式(singleTask):該模式是一種單例模式,即一個任務棧內只能有一個Activity實例;在該模式下,可以在AndroidManifest文件中指定能夠該Activity加載到哪個任務棧中(此時需要singleTask與taskAffinity配合使用,指定Activity加載到哪個任務棧);

taskAffinity:每個Activity都有taskAffinity這個屬性,這個屬性指出該Activity需要被加載到哪個任務棧內;如果沒有顯性指明該Activity的taskAffinity,那么這個值等于Application指明的taskAffinity,如果Application的taskAffinity也沒有指明,那么該taskAffinity的值等于包名;

該模式下的執行過程:啟動一個Activity,如果該Activity指定的棧不存在,則創建一個任務棧,并把該Activity置于棧頂;如果該任務棧存在,但Activity不在該棧中,則創建Activity置于棧頂;如果棧存在且Activity處于棧中,則把Activity上面的所有Activity銷毀并清除,重用Activity置于棧頂,并回調onNewIntent方法;

應用場景:大多數的APP的主頁,我們都是在主界面時,按下back鍵才退出APP,因此,我們不管打開了多少個Activity,只要我們回到主界面,主界面上的所有Activity都應被銷毀,讓主界面的Activity處于棧頂,而不是往棧頂添加一個新的主界面的Activity,所以退出應用時,所有的Activity都會被銷毀;

4.單例模式(singleInstance):棧內復用模式的加強版,打開一個新的Activity的時候,直接創建一個新的任務棧,并創建該Activity實例放入新的任務棧內;一旦該模式的Activity實例已經處于某個棧內,任何應用激活該Activity時都會重用該棧內的實例;

應用場景:呼叫來電界面;這種模式比較罕見,比較少用到;
4. Activity的Flags:
Activity中的Flags有很多,比如:
1.FLAG_ACTIVITY_NEW_TASK:效果與指定了singleTask啟動模式的效果一樣; 
2.FLAG_ACTIVITY_SINGLE_TOP:效果與指定了singleTop的效果一樣; 
3.FLAG_ACTIVITY_CLEAR_TOP:具有此標記位的Activity,當啟動時,在同一個任務棧中所有位于它上面的Activity都要出棧;

如果與singleTask模式結合使用:若被啟動的Activity已經存在于棧中,則清除其上的所有Activity,并使該Activity置于棧頂,并調用onNewIntent方法; 
如果與Standard模式結合使用:,那么該Activity與其上的所有Activity都會出棧,然后重新創建一個新的該Activity實例壓入棧中;

IntentFilter匹配規則
Activity的啟動可以分為兩種:顯示調用、隱式調用;
1.顯示調用:需要明確指定被啟動對象的組件信息,包括包名與類名; 
2.隱式調用:需要Intent能夠匹配目標組件的IntentFilter中所設置的匹配規則(過濾信息);過濾信息有:action、category、data;只有一個Intent同時匹配action、category、data才算完全匹配,只有完全匹配才能成功啟動Activity;

1. action(行為):
1.action是一個字符串,系統預定義了一些action,同時我們也可以在應用中定義自己的action; 
2.匹配規則:Intent中的action必須能夠和過濾規則中的action匹配,這里匹配是指字符串值完全一樣; 
3.一個過濾規則中有多個action,只要Intent中action能夠和過濾規則的任何一個action相同就可匹配成功;即要求Intent中的action存在且必須和過濾規則中的其中一個action相同;

2. category(類別):
1.匹配規則:要求Intent中如果含有category,那么所有的category都必須和過濾規則中的其中一個category相同;換句話說,Intent中如果出現了category,那么不管有幾個category,對于每個category來說,必須是過濾規則中已經定義了的category; 
2.category與action的不同:action是要求Intent中必須有一個action且必須能夠和過濾規則中的某個action相同,而category要求Intent中可以沒有category,但一旦擁有,不管有幾個,每個都要能夠和過濾規則中的任何一個相同; 
3.category可以有,也可以不設置,不設置的時候,調用startActivity或者startActivityForResult的時候會默認為Intent加上DEFAULT這個category;同時,為了使activity能夠隱式調用,就必須在intent-filter中指定DEFAULT這個category;

3. data(數據):
1.data的結構稍微有點復雜,就不深究了;但是data的匹配規則與action的匹配規則是類似的;

注意:
當我們隱式調用activity的時候,看是否有Activity能夠匹配我們隱式的Intent,判斷方法有: 
1.采用PackageManager的resolveActivity方法(還有一個queryIntentActivities,返回所有成功匹配Activity的信息)或者Intent的resolveActivity方法,找不到匹配的Activity就可以返回null,從而可以判斷該返回值進行規避錯誤; 
2.不含有DEFAULT這個category的Activity是不可以接收隱式Intent的;


我來說兩句
您需要登錄后才可以評論 登錄 | 立即注冊
facelist
所有評論(0)
領先的中文移動開發者社區
18620764416
7*24全天服務
意見反饋:[email protected]

掃一掃關注我們

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粵ICP備15117877號 )

两码中特期期