申明:文章并不介绍Activity的四种启动模式,而是帮助读者理解Activity与活动任务栈之间的关系
开发过程中,为满足各种业务需求,开发者需要灵活运用Activity的四种启动模式,这里就不介绍启动模式的具体用法了,通常我们通过指定`launchMode`就能解决大部分的问题,而对活动任务记录栈的理解只是停留在抽象的概念当中。为了更好地理解活动任务栈,本文将通过实际的数据演示,来帮助理解TaskRecord。
首先,通过activity的`taskAffinity`属性,可以指定activity的活动任务记录栈,在不指定`taskAffinity`的条件下,启动时入口Activity的默认TaskRecord为软件包名applicationId,随后被启动的Activity的TaskRecord默认与启动它的Activity一致。通过建立一个简单的Android项目,并对Manifast.xml进行如下配置,可以让我们更好理解两者之间的关系:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.student0.ada01">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize"
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:configChanges="screenLayout"
android:label="@string/app_name"
android:taskAffinity="com.example.student.task1"
android:launchMode="singleTask"
/>
<activity
android:name=".ThirdActivity"
android:configChanges="screenLayout"
android:taskAffinity="com.example.student.task1"
android:launchMode="singleTask"
/>
</application>
</manifest>
这样便指定了`SecondActivity`和`ThirdActivity`的活动任务堆栈为`com.example.student.task1`,为了区别包名这个笼统的概念,这里笔者将软件的唯一标识applicationId,改为了"com.example.student0.ada101",然后分别在每个Activity中添加`Button`实现Activity路由,路由的规则如下:
MainActivity-->SecondActivity-->ThirdActivity->MainActivity
接着,由Main点击跳转至Second,再由Second点击跳转至Third,再由Third点击跳转至Main。
然后,在commend模式下输入:`adb shell dumpsys activity`(为了减少其他程序信息的干扰,可以将其他的app后台kill掉),最后对数据进行分析:
系统首先启动MainActivity,由于没有设置taskAffinity属性,此时系统将建立第一个管理活动的Task,且Task的TaskRecord名字与applicationId一致,当通过MainActivity启动SecondActivity时,由于此时已经指定了SecondActivity的TaskAffinity属性为`com.example.student0.task1`,系统将寻找TaskRecord为`com.example.student0.task1`的Task,如果不存在则建立一个满足要求的Task,如果Activity指定的TaskRecord已存在,该Activity则交由此TaskRecord维护,这一点可以从SecondActivity启动ThirdActivity中看出。最后,由于MainActivity并未指定TaskAffinity属性,且LaunchMode也是默认的Standard,所以当使用ThirdActivity启动MainActivity时,在ThirdActivity所在的Task中的TaskRecord将再次创建并维护一个MainActivity。
而此时后台也将有两个任务描述符出现: