activity的啟動模式,任務和回退棧進行了較為詳盡的分析。
但是有一些重點可能沒有很清楚地描述出來,下面就來分析一下。當然前提條件是你基本了解谷歌關於activity的啟動模式的官方文件中的內容,任務,回退棧,啟動模式,taskaffinity屬性等。
它是< activity >的乙個重要屬性,有以下特點:
1.taskaffinity指示當前 activity優先屬於哪個任務。
2.在概念上,具有相同taskaffinity的activity(即設定了相同taskaffinity屬性的activity)屬於同乙個任務。
3.這個屬性決定兩件事:
當activity被reparent時,它可以被reparent到哪個任務中。 當activity以flag_activity_new_task標誌啟動時,它會被啟動到哪個任務中。
4.預設情況下,乙個應用中的所有activity具有相同的taskaffinity,即應用程式的包名。
我們可以通過設定不同的taskaffinity屬性給應用中的activity分組,也可以把不同的應用中的activity的taskaffinity設定成相同的值。
5.只設定這乙個屬性沒有作用,必須和intent的flag或者launchmode配合使用。
從原始碼來看,intent.flag_activity_new_task是啟動模式中最關鍵的乙個flag,依據該flag啟動模式可以分成兩類,設定了該屬性的與未設定該屬性的。
對於非activity啟動的activity(比如service中啟動的activity)需要顯示的設定intent.flag_activity_new_task,而singletask及singleinstance在ams中被預處理後,**的設定了intent.flag_activity_new_task。
而啟動模式是standard及singlettop的activity不會被設定intent.flag_activity_new_task,除非通過顯示的intent setflag進行設定。
flag_activity_new_task這個屬性更多的關注點是在task,大多數情況下,需要將activity引入到自己taskaffinity的task中,intent.flag_activity_new_task的初衷是在activity目標taskaffinity的task中啟動,非activity(比如在service中啟動activity)啟動activity都必須新增intent.flag_activity_new_task才行。
假設我們現在要啟動乙個activitytestactivity,它的taskaffinity值為com.tingshuonitiao.test,並且我們在啟動的時候給intent加上了flag–intent.flag_activity_new_task。
那麼在啟動它的時候,我們會做如下分析:
如果存在com.tingshuonitiao.test這樣的乙個任務,則檢查在這個任務中是否已經有了乙個testactivity的例項。
如果已經存在乙個testactivity的例項,並且它是棧的根activity,啟動該activity的intent和當前intent相等,則會重用這個任務和任務中的testactivity例項,將這個任務調到前台,清除位於testactivity上面的所有activity,顯示testactivity,並呼叫testactivity的onnewintent()。
如果不滿足(1)已經存在乙個testactivity的例項,(2)並且它是棧的根activity,(3)啟動該activity的intent和當前intent相等這三個條件中的一條,就會在這個任務中建立testactivity新的例項,並呼叫oncreate()。
如果不存在com.tingshuonitiao.test這樣的乙個任務,會建立乙個新的taskaffinity為com.tingshuonitiao.test的任務,並且將testactivity啟動到這個新的任務中去。
以上所指的intent相等,就是說兩次啟動activity的intent屬性要完全一樣。
假設我們要啟動的testactivity是乙個根activity,正常啟動應用的時候它就是應用的入口,直接就開啟了。在清單檔案中有如下配置:
那麼我們現在在另乙個任務中要去啟動它就要給intent加上兩條對應的屬性:
intent.setaction("android.intent.action.main");
intent.addcategory("android.intent.category.launcher");否則就不能滿足intent相等的要求,達不到所要的效果了。
singletask啟動模式預設是加了intent.flag_activity_new_task這個flag的,意味著可以在乙個新的任務中開啟,至於是不是真的會在新任務中開啟,還要根據其他設定分析。
當然singletask還有一點很重要的意思就是「single in task」,即在同乙個任務中,只會有乙個該activity的例項。
還是假設我們現在要啟動乙個activitytestactivity,它的taskaffinity值為com.tingshuonitiao.test,並且它的launchmode是singletask。
那麼在啟動它的時候,我們會做如下分析:
如果存在com.tingshuonitiao.test這樣的乙個任務,則檢查在這個任務中是否已經有了乙個testactivity的例項。
如果已經存在乙個testactivity的例項,則會重用這個任務和任務中的testactivity例項,將這個任務調到前台,清除位於testactivity上面的所有activity,顯示testactivity,並呼叫testactivity的onnewintent()。
如果不存在乙個testactivity的例項,會在這個任務中建立testactivity的例項,並呼叫oncreate()。
如果不存在com.tingshuonitiao.test這樣的乙個任務,會建立乙個新的taskaffinity為com.tingshuonitiao.test的任務,並且將testactivity啟動到這個新的任務中去。
使用的時候記得新增exported這一屬性,它預設值是false,如果被設定為了false,那麼這個activity將只會被當前application或者擁有同樣user id的application的元件呼叫。
我們使用的時候修改為true,所以在清單檔案中做如下配置:
android:allowtaskreparenting="true"
android:exported="true"這樣的話,就能成功地達到reparenting的效果了。
以上就是很有可能混淆或者遺漏的一些重點。
activity 啟動模式
在android的中activity 有4種啟動方式 standard singletop singletask singleinstance 下面就分輕重點講講這些啟動方式。1 standard啟動方式 這種方式也是系統預設的。說的簡單點,我們在使用startactivity 方法的時候,系統就會...
activity啟動模式
1 對於使用standard 模式的活動,系統不會在乎這個活動是否已經在返回棧中存在,每次啟動都會建立該活動的乙個新的例項。例如a啟動a,a再接著啟動a,a繼續啟動a,然後再分別出棧,如圖所示 2 當活動的啟動模式指定為 singletop,在啟動活動時如果發現返回棧的棧頂已經是該活動,則認為可以直...
Activity啟動模式
兩種方式可以定義activity啟動模式 manifest intent intent定義的啟動模式優先於manifest 不管activity執行在乙個新的任務還是與啟動它的activity同樣的任務,返回鍵總是把使用者帶到之前的activity。然而,如果啟動乙個singletask的activ...