Activity的啓動方式和flag詳解

Activity的4種狀態:android

活動的:當一個Activity在棧頂,它是可視的、有焦點、可接受用戶輸入的。Android試圖盡最大可能保持它活動狀態,殺死其它Activity來確保當前活動Activity有足夠的資源可以使用。當另一個Activity被激活,這個將會被暫停。app

暫停:在不少狀況下,你的Activity可視可是它沒有焦點,換句話說它被暫停了。有可能緣由是一個透明或者非全屏的Activity被激活。動畫

當被暫停,一個Activity仍會當成活動狀態,只不過是不能夠接受用戶輸入。在極特殊的狀況下,Android將會殺死一個暫停的Activity來爲活動的Activity提供充足的資源。當一個Activity變爲徹底隱藏,它將會變成中止。this

中止:當一個Activity不是可視的,它「中止」了。這個Activity將仍然在內存中保存它全部的狀態和會員信息。儘管如此,當其它地方須要內存時,它將是最有可能被釋放資源的。當一個Activity中止後,一個很重要的步驟是要保存數據和當前UI狀態。一旦一個Activity退出或關閉了,它將變爲待用狀態。spa

待用: 在一個Activity被殺死後和被裝在前,它是待用狀態的。待用Acitivity被移除Activity棧,而且須要在顯示和可用以前從新啓動它。xml

 

Activity的4種加載模式:生命週期

在android的多activity開發中,activity之間的跳轉可能須要有多種方式,有時是普通的生成一個新實例,有時但願跳轉到原來某個activity實例,而不是生成大量的重複的activity。加載模式即是決定以哪一種方式啓動一個跳轉到原來某個Activity實例。事件

在android裏,有4種activity的啓動模式,分別爲:圖片

standard: 標準模式,一調用startActivity()方法就會產生一個新的實例。ip

singleTop: 來了intent, 每次都建立新的實例,僅一個例外:當棧頂的activity 偏偏就是該activity的實例(即須要建立的實例)時,再也不建立新實例。這解決了棧頂複用問題

singleTask: 來了intent後,檢查棧中是否存在該activity的實例,若是存在就把intent發送給它,不然就建立一個新的該activity的實例,放入一個新的task棧的棧底。確定位於一個task的棧底,並且棧中只能有它一個該activity實例,但容許其餘activity加入該棧。解決了在一個task中共享一個activity。

singleInstance: 這個跟singleTask基本上是同樣,只有一個區別:在這個模式下的Activity實例所處的task中,只能有這個activity實例,不能有其餘的實例。一旦該模式的activity的實例已經存在於某個棧中,任何應用在激活該activity時都會重用該棧中的實例,解決了多個task共享一個activity。

這些啓動模式能夠在功能清單文件AndroidManifest.xml中進行設置,中的launchMode屬性。

影響加載模式的一些特性:

核心的Intent Flag有:

FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP
核心的特性有:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch

Activity在Activity棧(Task)中的加載順序是能夠控制的,這就須要用到Intent Flag

 

Intent經常使用標識:

FLAG_ACTIVITY_BROUGHT_TO_FRONT 
    這個標誌通常不是由程序代碼設置的,如在launchMode中設置singleTask模式時系統幫你設定。

FLAG_ACTIVITY_CLEAR_TOP
    若是設置,而且這個Activity已經在當前的Task中運行,所以,再也不是從新啓動一個這個Activity的實例,而是在這個Activity上方的全部Activity都將關閉,而後這個Intent會做爲一個新的Intent投遞到老的Activity(如今位於頂端)中。
    例如,假設一個Task中包含這些Activity:A,B,C,D。若是D調用了startActivity(),而且包含一個指向Activity B的Intent,那麼,C和D都將結束,而後B接收到這個Intent,所以,目前stack的情況是:A,B。
    上例中正在運行的Activity B既能夠在onNewIntent()中接收到這個新的Intent,也能夠把本身關閉而後從新啓動來接收這個Intent。若是它的啓動模式聲明爲 「multiple」(默認值),而且你沒有在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標誌,那麼它將關閉而後從新建立;對於其它的啓動模式,或者在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標誌,都將把這個Intent投遞到當前這個實例的onNewIntent()中。
    這個啓動模式還能夠與FLAG_ACTIVITY_NEW_TASK結合起來使用:用於啓動一個Task中的根Activity,它會把那個Task中任何運行的實例帶入前臺,而後清除它直到根Activity。這很是有用,例如,當從Notification Manager處啓動一個Activity。

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
    若是設置,這將在Task的Activity stack中設置一個還原點,當Task恢復時,須要清理Activity。也就是說,下一次Task帶着 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED標記進入前臺時(典型的操做是用戶在主畫面重啓它),這個Activity和它之上的都將關閉,以致於用戶不能再返回到它們,可是能夠回到以前的Activity。
    這在你的程序有分割點的時候頗有用。例如,一個e-mail應用程序可能有一個操做是查看一個附件,須要啓動圖片瀏覽Activity來顯示。這個 Activity應該做爲e-mail應用程序Task的一部分,由於這是用戶在這個Task中觸發的操做。然而,當用戶離開這個Task,而後從主畫面選擇e-mail app,咱們可能但願回到查看的會話中,但不是查看圖片附件,由於這讓人困惑。經過在啓動圖片瀏覽時設定這個標誌,瀏覽及其它啓動的Activity在下次用戶返回到mail程序時都將所有清除。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    若是設置,新的Activity不會在最近啓動的Activity的列表中保存。

FLAG_ACTIVITY_FORWARD_RESULT
    若是設置,而且這個Intent用於從一個存在的Activity啓動一個新的Activity,那麼,這個做爲答覆目標的Activity將會傳到這個新的Activity中。這種方式下,新的Activity能夠調用setResult(int),而且這個結果值將發送給那個做爲答覆目標的 Activity。

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY 
    這個標誌通常不禁應用程序代碼設置,若是這個Activity是從歷史記錄裏啓動的(常按HOME鍵),那麼,系統會幫你設定。

FLAG_ACTIVITY_MULTIPLE_TASK 
    不要使用這個標誌,除非你本身實現了應用程序啓動器。與FLAG_ACTIVITY_NEW_TASK結合起來使用,能夠禁用把已存的Task送入前臺的行爲。當設置時,新的Task老是會啓動來處理Intent,而無論這是是否已經有一個Task能夠處理相同的事情。
    因爲默認的系統不包含圖形Task管理功能,所以,你不該該使用這個標誌,除非你提供給用戶一種方式能夠返回到已經啓動的Task。
    若是FLAG_ACTIVITY_NEW_TASK標誌沒有設置,這個標誌被忽略。

FLAG_ACTIVITY_NEW_TASK 
    若是設置,這個Activity會成爲歷史stack中一個新Task的開始。一個Task(從啓動它的Activity到下一個Task中的 Activity)定義了用戶能夠遷移的Activity原子組。Task能夠移動到前臺和後臺;在某個特定Task中的全部Activity老是保持相同的次序。
    這個標誌通常用於呈現「啓動」類型的行爲:它們提供用戶一系列能夠單獨完成的事情,與啓動它們的Activity徹底無關。
    使用這個標誌,若是正在啓動的Activity的Task已經在運行的話,那麼,新的Activity將不會啓動;代替的,當前Task會簡單的移入前臺。參考FLAG_ACTIVITY_MULTIPLE_TASK標誌,能夠禁用這一行爲。
    這個標誌不能用於調用方對已經啓動的Activity請求結果。

FLAG_ACTIVITY_NO_ANIMATION 
    若是在Intent中設置,並傳遞給Context.startActivity()的話,這個標誌將阻止系統進入下一個Activity時應用 Acitivity遷移動畫。這並不意味着動畫將永不運行——若是另外一個Activity在啓動顯示以前,沒有指定這個標誌,那麼,動畫將被應用。這個標誌能夠很好的用於執行一連串的操做,而動畫被看做是更高一級的事件的驅動。

FLAG_ACTIVITY_NO_HISTORY 
    若是設置,新的Activity將再也不歷史stack中保留。用戶一離開它,這個Activity就關閉了。這也能夠經過設置noHistory特性。

FLAG_ACTIVITY_NO_USER_ACTION 
    若是設置,做爲新啓動的Activity進入前臺時,這個標誌將在Activity暫停以前阻止從最前方的Activity回調的onUserLeaveHint()。
    典型的,一個Activity能夠依賴這個回調指明顯式的用戶動做引發的Activity移出後臺。這個回調在Activity的生命週期中標記一個合適的點,並關閉一些Notification。
    若是一個Activity經過非用戶驅動的事件,如來電或鬧鐘,啓動的,這個標誌也應該傳遞給Context.startActivity,保證暫停的Activity不認爲用戶已經知曉其Notification。

FLAG_ACTIVITY_PREVIOUS_IS_TOP 
    If set and this intent is being used to launch a new activity from an existing one, the current activity will not be counted as the top activity for deciding whether the new intent should be delivered to the top instead of starting a new one. The previous activity will be used as the top, with the assumption being that the current activity will finish itself immediately. 

FLAG_ACTIVITY_REORDER_TO_FRONT
    若是在Intent中設置,並傳遞給Context.startActivity(),這個標誌將引起已經運行的Activity移動到歷史stack的頂端。
    例如,假設一個Task由四個Activity組成:A,B,C,D。若是D調用startActivity()來啓動Activity B,那麼,B會移動到歷史stack的頂端,如今的次序變成A,C,D,B。若是FLAG_ACTIVITY_CLEAR_TOP標誌也設置的話,那麼這個標誌將被忽略。

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

If set, and this activity is either being started in a new task or bringing to the top an existing task, then it will be launched as the front door of the task. This will result in the application of any affinities needed to have that task in the proper state (either moving activities to or from it), or simply resetting that task to its initial state if needed. 

FLAG_ACTIVITY_SINGLE_TOP
    若是設置,當這個Activity位於歷史stack的頂端運行時,再也不啓動一個新的。 

注意:若是是從BroadcastReceiver啓動一個新的Activity,或者是從Service往一個Activity跳轉時,不要忘記添加Intent的Flag爲FLAG_ACTIVITY_NEW_TASK。

相關文章
相關標籤/搜索