3-Activity的四種啓動模式

Activity的四種啓動模式

 

任務棧Task,是一種用來放置Activity實例的容器,他是以棧的形式進行盛放,也就是所謂的先進後出,主要有2個基本操作:壓棧和出棧,其所存放的Activity是不支持重新排序的,只能根據壓棧和出棧操作更改Activity的順序。啓動一個Application的時候,系統會爲它默認創建一個對應的Task,用來放置根Activity。默認啓動Activity會放在同一個Task中,新啓動的Activity會被壓入啓動它的那個Activity的棧中,並且顯示它。當用戶按下回退鍵時,這個Activity就會被彈出棧,按下Home鍵回到桌面,再啓動另一個應用,這時候之前那個Task就被移到後臺,成爲後臺任務棧,而剛啓動的那個Task就被調到前臺,成爲前臺任務棧,手機頁面顯示的就是前臺任務棧中的棧頂元素。

 

standard

 

標準模式:在清單文件中聲明 Activity 時,如果不設置Activity的啓動模式,系統會 默認 將其設置爲standard。每次啓動一個標準模式的Activity都會重新創建一個新的實例,不管這個Activity之前是否已經存在實例,一個任務棧中可以有多個實例,每個實例也可以屬於不同的任務棧,誰啓動了這個Activity,那麼這個Activity實例就運行在啓動它的那個Activity所在的棧中 。根據上面所說,我們就瞭解了當用ApplicationContext啓動或者在Service中直接調用startActivity啓動標準模式Activity時報如下錯誤的原因了。

android.util.AndroidRuntimeException: Calling startActivity from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

上面錯誤的原因就是被啓動的Activity是標準模式,而發起啓動請求的Context不是Activity的Context,未存在Activity棧,而每個Activity實例啓動銷燬都需要進棧出棧,用棧來存儲Activity的信息,所以非Activity Context需要設置FLAG_ACTIVITY_NEW_TASK屬性,啓動一個新的Activity棧。

 

singleTop

 

棧頂複用模式:在這種模式下,如果新啓動的Activity已經位於任務戰的棧頂,那麼此Activity不會被重新創建,只會重新調用 onNewIntent 方法,這個Activity的onCreate、onStart都不會被系統調用。如果新Activity實例已經存在但不在棧頂,那麼重新創建 Activity 並放入棧頂。

 

singleTask

 

棧內複用模式:這是一種單實例模式,一個棧中同一個Activity只存在唯一一個實例,無論是否在棧頂,只要存在實例,都不會重新創建,和 singleTop 一樣會重新調用 onNewIntent 方法。需要注意的是:如果一個Activity被設置爲singleTask模式,那麼當棧內已經存在該Activity實例時,再啓動該Activity,會讓該Activity實例之上的Activity被出棧。舉個例子:有四個Activity 分別是 A、B、C和D,A是singleTask模式,當先執行A->B->C->D時,A在棧內已存在實例,此時再調用D->A啓動A時,會讓A實例之上的B、C、D都出棧。一般項目的MainActivity都設置爲此模式,方便放回首頁和清空中間Activity。

 

singleInstance

 

單實例模式:這是一種加強的singleTask模式,它除了具有singleTask模式的所有特性外,還加強了一點,那就是此種模式的Activity只能單獨地位於一個任務棧中,不同的應用去打開這個activity 共享公用的同一個activity。他會運行在自己單獨,獨立的任務棧裏面,並且任務棧裏面只有他一個實例存在。應用場景:呼叫來電界面。這種模式的使用情況比較罕見,在Launcher中可能使用。或者你確定你需要使Activity只有一個實例。

 

啓動模式有2種設置方式:在AndroidMainifest設置、通過Intent設置標誌位

 

在AndroidMainifest的Activity配置進行設置

 

<activity

android:name="com.demo.Main4Activity"

//通過android:launchMode屬性設置

android:launchMode="singleTask"/>

 

通過Intent設置標誌位

Intent inten = new Intent (ActivityA.this,ActivityB.class);

//通過Intent的Flag設置

intent,addFlags(Intent,FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

 

標記爲屬性

FLAG_ACTIVITY_SINGLE_TOP 指定啓動模式爲棧頂複用模式(SingleTop)

FLAG_ACTIVITY_NEW_TASK 指定啓動模式爲棧內複用模式(SingleTask)

FLAG_ACTIVITY_CLEAR_TOP 所有位於其上層的Activity都要移除,SingleTask模式默認具有此標記效果

 

鏈接:https://www.jianshu.com/p/7e70ee765513

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章