看到這個題目估計又有人說我標題黨了,啓動模式跟多進程有什麼關係,沒啥關係,我只是在寫Activity啓動模式的demo的時候,用到了多進程進行測試,順便一塊兒交代一下。java
不知道有沒有人想固然的混淆上述兩個概念,我是見過有這樣想的開發者。android
Task就是一堆Activity的集合,你能夠這樣想,一個棧中,有多個Activity,當用戶在多個activity之間跳轉時,執行壓棧操做,當用戶按返回鍵時,執行出棧操做。 在作測試以前,咱們須要先介紹一下Task相關的代碼。 在Activity中,直接調用getTaskId()
能夠獲取當前Activity所在的Task_id。 咱們也能夠調用系統方法,獲取Task的相關信息:git
public static void getTask(Context context){
ActivityManager mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<AppTask> list = mAm.getAppTasks();
for (AppTask appTask:list){
Log.e("Utils",context.getClass().getName()+" "+appTask.getTaskInfo().affiliatedTaskId+"的num = "+appTask.getTaskInfo().numActivities);
}
}
複製代碼
咱們設置四個Activity,每一個Activity的啓動模式都設置成standard。來看一下Task的相關狀況。 github
上圖是用上面介紹的代碼完成的一個demo,從第一個Actvity切換到第四個Activity,每增長一個ActivityTask都會增長一個Activity,若是按返回鍵,即銷燬一個Activity,根據上圖所知,ActivityTask會減小一個。若是不斷的startActivity則ActivityTask數量不斷增長。shell
咱們設置四個Activity,每一個Activity的啓動模式都設置成singleTask。來看一下Task的相關狀況。 bash
由上圖可知,若是一個activity的啓動模式爲singleTask,那麼Task棧中將會只有一個該Activity的實例。因此從第一個activity,跳到第四個Activity,再跳回第一個的時候,只是將第一個Activity啓動了,同時調用了第一個Activity的onNewIntent
這裏還有一個有趣的事,注意觀察上圖,再回到第一個Activity的時候,Task中Activity的數量變爲了1,也就是singleTask除了啓動了第一個Activity,並將第一個Activity順序之上的activity所有銷燬了。app
咱們設置四個Activity,每一個Activity的啓動模式都設置成singleTop。來看一下Task的相關狀況。 ide
咱們設置四個Activity,每一個Activity的啓動模式都設置成singleInstance。來看一下Task的相關狀況。 測試
如今聊一下與進程相關的東西this
首先先說的是taskAffinity,爲何在Process標題下聊taskAffinity,由於進程間咱們能夠看到的taskAffinity屬性,更明顯的特性。 接着須要引出的概念就是taskAffinity,taskAffinity表示當前activity具備親和力的一個Task,能夠這樣理解, taskAffinity表示一個Task的名字,這個Task就是當前activity所在的Task。一個Task的taskAffinity取決於跟Activity的taskAffinity。 若是一個Activity沒有顯式的指明該 Activity的taskAffinity,那麼它的這個屬性就等於Application指明的taskAffinity,若是 Application也沒有指明,那麼該taskAffinity的值就等於包名。 如今來示範一個例子(全部的例子,都有demo,在文章的最後),新建兩個應用,app,app2,每一個應用都有MainActivity,和SecondActivity,從MainActivity能夠跳到SecondActivity,爲了方便描述,咱們appMain,appSecond,app2Main,app2Second來代替。 咱們將appSecond和app2Second設置成一樣的taskAffinity:
<activity android:name=".MainActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SecondActivity"
android:taskAffinity="com.deep"
>
</activity>
複製代碼
啓動這兩個Activity,發現沒有什麼特殊效果,appSecond都在各自應用的應用根Activity的Task中。 這時咱們改一下代碼將appSecond設置成singleTask,這樣appSecond所在的Task就是帶有taskAffinity屬性的了。 而後這時咱們再啓動app2Second:
adb shell dumpsys activity activities
查看一下activity的堆棧信息:
關於多進程,能夠共用Task的例子,也能夠這樣證實:
<activity android:name=".MainActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SecondActivity"
android:process="com.deep1"
android:launchMode="standard"
>
</activity>
<activity android:name=".ThirdActivity"
android:process="com.deep2"
android:launchMode="standard">
</activity>
<activity android:name=".FourthActivity"
android:launchMode="standard">
</activity>
複製代碼
在一個app中啓用多進程,但全部的Activity都是標準模式,能夠發現,全部的Activity都在同一個Task中。
Activity均可以設置進程的歸屬關係,可是若是不是Activity,而是一個全局變量呢?能夠試一下,咱們創建一個全局變量:
public class StaticParam {
public static String a = "default";
public static Object o = new Object();
}
複製代碼
首先在Application中初始化:
@Override
public void onCreate() {
super.onCreate();
StaticParam.a ="init";
Log.e("xxxxxx","application:"+Utils.getCurProcessName(this)+ " "+StaticParam.a.getClass().toString());
}
複製代碼
而後在上面例子中的四個Activity中的onCreate添加以下代碼:
StaticParam.a = StaticParam.a+ " "+getClass().getSimpleName();
Log.e("xxxxxx","a="+StaticParam.a+" "+StaticParam.o+" "+Utils.getCurProcessName(this));
複製代碼
執行一遍全部的activity,看一下效果:
12-27 10:56:32.993 31195-31195/umeng.com.testlauncher E/xxxxxx: application:umeng.com.testlauncher class java.lang.String
12-27 10:56:33.053 31195-31195/umeng.com.testlauncher E/xxxxxx: a=init MainActivity java.lang.Object@76794cc umeng.com.testlauncher
12-27 10:56:40.000 31325-31325/? E/xxxxxx: application:com.deep1 class java.lang.String
12-27 10:56:40.057 31325-31325/? E/xxxxxx: a=init SecondActivity java.lang.Object@76794cc com.deep1
12-27 10:56:49.618 31486-31486/com.deep2 E/xxxxxx: application:com.deep2 class java.lang.String
12-27 10:56:49.674 31486-31486/com.deep2 E/xxxxxx: a=init ThirdActivity java.lang.Object@76794cc com.deep2
12-27 10:56:51.202 31195-31195/umeng.com.testlauncher E/xxxxxx: a=init MainActivity FourthActivity java.lang.Object@76794cc umeng.com.testlauncher
複製代碼
根據log,咱們發現幾個問題:
a=init MainActivity
可是SecondActivity添加了本身的名字倒是a=init SecondActivity
,等到與MainActivity同進程的FourthActivity的時候,又變回a=init MainActivity FourthActivity
,這說明全局靜態變量在各個進程間是不通用的,每一個進程各自維護各自的,互不干擾。demo地址:https://github.com/mymdeep/activityTest 暫時就想到了這些,寫的有點亂,想到哪寫到哪,若有問題,歡迎進一步討論 也歡迎關注個人公衆號,以後會推薦更多好用的組件庫。