11.Activity啟動模式

Android中Activity四種啟動模式和taskAffinity屬性詳解

Application,Task和Process

  1. Application是一組組件的集合
  2. task是一組相互關(guān)聯(lián)的activity的集合
    task是可以跨應(yīng)用的,這正是task存在的一個重要原因。有的Activity,雖然不在同一個app中,但為了保持用戶操作的連貫性,把他們放在同一個任務(wù)中。例如,在我們的應(yīng)用中的一個Activity A中點擊發(fā)送郵件,會啟動郵件程序的一個Activity B來發(fā)送郵件,這兩個activity是存在于不同app中的,但是被系統(tǒng)放在一個任務(wù)中,這樣當(dāng)發(fā)送完郵件后,用戶按back鍵返回,可以返回到原來的Activity A中,這樣就確保了用戶體驗。
  3. 在默認(rèn)情況下,一個應(yīng)用程序的所有組件運行在同一個進(jìn)程中。但是這種情況也有例外,即,應(yīng)用程序中的不同組件可以運行在不同的進(jìn)程中。只需要在manifest中用process屬性指定組件所運行的進(jìn)程的名字。

1. standard

每次都會實例化一個。

2. singleTop

  1. 如果一個以singleTop模式啟動的activity的實例已經(jīng)存在于任務(wù)桟的桟頂,那么再啟動這個Activity時,不會創(chuàng)建新的實例,而是重用位于棧頂?shù)哪莻€實例,并且會調(diào)用該實例的onNewIntent()方法將Intent對象傳遞到這個實例中。
  2. 如果以singleTop模式啟動的activity的一個實例已經(jīng)存在與任務(wù)桟中,但是不在桟頂,那么它的行為和standard模式相同,也會創(chuàng)建多個實例。

3. singleTask

把啟動模式設(shè)置為singleTask,framework在啟動該activity時只會把它標(biāo)示為可在一個新任務(wù)中啟動(類似FLAG_ACTIVITY_NEW_TASK),至于是否在一個新任務(wù)中啟動,還要受其他條件的限制。

**taskAffinity**是manifest文件中<activity>的一個重要屬性
1. taskAffinity表示當(dāng)前activity具有親和力的一個任務(wù),這個taskAffinity表示一個任務(wù),這個任務(wù)就是當(dāng)前activity所在的任務(wù)。
在概念上,具有相同的affinity的activity(即設(shè)置了相同taskAffinity屬性的activity)屬于同一個任務(wù)。
2. 默認(rèn)情況下,**一個應(yīng)用中的所有activity具有相同的taskAffinity**,即應(yīng)用程序的包名。我們可以通過設(shè)置不同的taskAffinity屬性給應(yīng)用中的activity分組,也可以把**不同的應(yīng)用中的activity的taskAffinity設(shè)置成相同的值**。
3. 為一個activity的taskAffinity設(shè)置一個空字符串,表明這個activity不屬于任何task。
**SecondActivity沒設(shè)置singleTask,設(shè)置taskAffinity的情況:**
a. 如果存在這樣的一個任務(wù),則檢查在這個任務(wù)中是否已經(jīng)有了一個SecondActivity的實例,如果已經(jīng)存在一個SecondActivity的實例,則會重用這個任務(wù)和任務(wù)中的SecondActivity實例,將這個任務(wù)調(diào)到前臺,清除位于SecondActivity上面的所有Activity,顯示SecondActivity,并調(diào)用SecondActivity的onNewIntent();
b.如果不存在一個SecondActivity的實例,會在這個任務(wù)中創(chuàng)建SecondActivity的實例,并調(diào)用onCreate()方法
如果不存在這樣的一個任務(wù),會創(chuàng)建一個新的affinity為com.jg.zhang.androidtasktest.second的任務(wù),并且將SecondActivity啟動到這個新的任務(wù)中.
**SecondActivity只設(shè)置啟動模式為singleTask,而不設(shè)置taskAffinity,即三個Activity的taskAffinity相同,都為應(yīng)用的包名,那么SecondActivity是不會開啟一個新任務(wù)的**
1. 在MainActivity啟動SecondActivity時,發(fā)現(xiàn)啟動模式為singleTask,那么設(shè)定他的啟動標(biāo)志為FLAG_ACTIVITY_NEW_TASK
2. 然后獲得SecondActivity的taskAffinity,即為包名com.jg.zhang.androidtasktest
3. 檢查是否已經(jīng)存在一個affinity為com.jg.zhang.androidtasktest的任務(wù),這個任務(wù)是存在的,就是MainActivity所在的任務(wù),這個任務(wù)是在啟動MainActivity時開啟的
4. 既然已經(jīng)存在這個任務(wù),就檢索在這個任務(wù)中是否存在一個SecondActivity的實例,發(fā)現(xiàn)不存在
5.在這個已有的任務(wù)中啟動一個SecondActivity的實例
**SecondActivity啟動模式設(shè)為singleTask,并且taskAffinity設(shè)為com.jg.zhang.androidtasktest.second時的啟動過程:
1. 在MainActivity啟動SecondActivity時,發(fā)現(xiàn)啟動模式為singleTask,那么設(shè)定他的啟動標(biāo)志為FLAG_ACTIVITY_NEW_TASK
2. 然后獲得SecondActivity的taskAffinity,即com.jg.zhang.androidtasktest.second
3. 檢查是否已經(jīng)存在一個affinity為com.jg.zhang.androidtasktest.second的任務(wù),這個任務(wù)是不存在的
4. 創(chuàng)建一個新的affinity為com.jg.zhang.androidtasktest.second的任務(wù),并且將SecondActivity啟動到這個新的任務(wù)中
兩個不同app中的不同的singleTask模式的Activity的taskAffinity設(shè)成相同驗證:**任務(wù)(Task)不僅可以跨應(yīng)用(Application),還可以跨進(jìn)程(Process)**

4. singleInstance

singleInstance的特點可以歸結(jié)為以下三條:

  1. 以singleInstance模式啟動的Activity具有全局唯一性,即整個系統(tǒng)中只會存在一個這樣的實例
  2. 以singleInstance模式啟動的Activity具有獨占性,即它會獨自占用一個任務(wù),被他開啟的任何activity都會運行在其他任務(wù)中(官方文檔上的描述為,singleInstance模式的Activity不允許其他Activity和它共存在一個任務(wù)中)
  3. 被singleInstance模式的Activity開啟的其他activity,能夠開啟一個新任務(wù),但不一定開啟新的任務(wù),也可能在已有的一個任務(wù)中開啟

使用場景

  1. singleTop
    解決問題:由于棧頂都是相同Activity而導(dǎo)致用戶出現(xiàn)BACK鍵失靈的錯覺
    a. APP的多個推送消息顯示在通知欄,你想把他們都給點了,每次點擊實際就是啟動某個Activity,這時候如果使用的是singleTop模式,就可以有效避免重復(fù)創(chuàng)建同一Activity實例的工作。
    b. 登錄成功跳轉(zhuǎn)到主頁,按下兩次登錄按鈕,生成了兩個主頁。一些有啟動延遲的頁面(往往是動畫,網(wǎng)絡(luò)造成)也會有這樣的情況。
  2. singleTask
    創(chuàng)建開銷較大且經(jīng)常被其他APP調(diào)用的Activity中使用,這種Activity一般作為程序的入口。例如瀏覽器的主界面。不管從多少個應(yīng)用啟動瀏覽器,只會啟動主界面一次,其余情況都會走onNewIntent,并且會清空主界面上面的其他頁面。
  3. singleInstance
    單一實例模式,整個手機(jī)操作系統(tǒng)里面只有一個實例存在。不同的應(yīng)用去打開這個activity共享公用的同一個activity。這樣的Activity封閉性極強(qiáng),能夠很好地保持唯一性,也能大大減少不必要的開銷。
    某個應(yīng)用中用到了google地圖 當(dāng)退出該應(yīng)用的時候,進(jìn)入google地圖,還是剛才的界面.
    鬧鈴的響鈴界面 你以前設(shè)置了一個鬧鈴:上午6點。在上午5點58分,你啟動了鬧鈴設(shè)置界面,并按 Home 鍵回桌面;在上午5點59分時,你在微信和朋友聊天;在6點時,鬧鈴響了,并且彈出了一個對話框形式的 Activity(名為 AlarmAlertActivity) 提示你到6點了(這個 Activity 就是以 SingleInstance 加載模式打開的),你按返回鍵,回到的是微信的聊天界面,這是因為 AlarmAlertActivity 所在的 Task 的棧只有他一個元素, 因此退出之后這個 Task 的??樟?。如果是以 SingleTask 打開 AlarmAlertActivity,那么當(dāng)鬧鈴響了的時候,按返回鍵應(yīng)該進(jìn)入鬧鈴設(shè)置界面。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容