看到这个题目估计又有人说我标题党了,启动模式跟多进程有什么关系,没啥关系,我只是在写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 暂时就想到了这些,写的有点乱,想到哪写到哪,若有问题,欢迎进一步讨论 也欢迎关注个人公众号,以后会推荐更多好用的组件库。