任务栈
- android任务栈又称为task,它是一个栈结构,具有先进后出的特性,用于存放我们的Activity组件
- 只有在栈顶的Activity才能与用户进行交互
- 我们退出程序时只有把任务栈中所有的Activity移除栈,任务栈才会被销毁,任务栈也可以移动到前台,并且保留了每一个Activity的状态,可以有序的给用户列出他们的任务,同时也不会丢失Activity的状态信息
- 一个App中可能不止一个任务栈,一个task的Activity可以来自不同的app,同一个app的Activity也可能不在一个task中
taskAffinity
属性
-
taskAffinity
为Activity的任务栈的名称,默认任务栈的名称为包名,并且必须包含. - 一般与
singleTask
、allowTaskReparenting
相结合
默认情况时
包名:com.wxx.lis1
<activity android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".MainActivity2"/>
通过使用adb shell dumpsys activity activities
命令查看任务栈信息
taskAffinity
与singleTask
结合
<activity android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".MainActivity2"
android:taskAffinity="com.wxx.affinity"
android:launchMode="singleTask"/>
通过测试我们发现,存在了两个任务栈,一个是默认的,一个是我们通过taskAffinity指定的。
taskAffinity
与 allowTaskReparenting
结合allowTaskReparenting
属性:转移任务栈,表示Activity
是否可以移动到taskAffinity
指定的任务栈中,true是允许,如果是false,taskAffinity
会失效。
当allowTaskReparenting=false
即默认情况下
App A 的MainActivity启动App B的 Activity,这个时候Activity的任务栈是A的任务栈,这个时候Activity点击home键,在重新进入App B,启动的便是B的MainActivity。这个时候如何去重新点击App A,前台界面依然是之前启动的Activity。
当allowTaskReparenting=true
当一个应用A启动了应用B的某个Activity(非主Activity),如果这个Activity的allowTaskReparenting=true
,那么当应用B被启动后,此Activity会直接从A的任务栈转移到B应用的任务栈中,此时如果在B应用中点击home键,再重新进入B时发现启动的并不是B的主Activity而是被A启动的那个Activity。
启动模式
standard
标准模式
每次都创建一个新的实例singleTop
栈顶复用模式
如果新Activity已经位于任务栈的栈顶,则不会再次创建Activity而是回调onNewIntent(),假设ABCD四个Activity,A位于栈底,D位于栈顶,如果再次启动D Activity,如果D的启动模式为singleTop模式,那么栈内情况还是ABCD,如果D是standard标准模式则栈内情况为ABCDDsingleTask
栈内复用模式
这是一种单实例模式,只要Activity存在栈内,多次启动都不会重新创建Activity,系统也会回调onNewIntent
3.1 比如任务栈S1有ABC,这个时候Activity D以singTask模式请求启动,其所需要的任务栈为S2,由于S2和D的实例都不存在,则先创建S2任务栈,然后再创建D的实例入栈到S2中
3.2 假设D所需任务栈为S1,在3.1情况下那么S1已经存在,所以系统直接创建D的实例入栈到S1中
3.3 假设D所需任务栈为S1,当前任务栈有ADBC,启动D根据栈内复用原则,D不会被重新创建而是切换到栈顶,同时singleTask具有clearTop的效果,此时BC会全部出栈,最终S1中只有ADsingleInstance
单实例模式singleTask
的加强版,singTask
所具有的特性其都具有,此模式系统会为其单独创建一个任务栈。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wxx.launchermode">
<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=".MainActivityA"
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=".MainActivityB"
android:taskAffinity="com.wxx.task_1"
android:launchMode="singleTask" />
<activity
android:name=".MainActivityC"
android:taskAffinity="com.wxx.task_1"
android:launchMode="singleTask" />
</application>
</manifest>
MainActivityA -> MainActivityB -> MainActivityC -> MainActivityA ->MainActivityB -> Back -> Back ->桌面
启动flags
Intent.FLAG_ACTIVITY_NEW_TASK
等同于XML指定singleTask模式Intent.FLAG_ACTIVITY_SINGLE_TOP
等同于XML指定singleTop模式Intent.FLAG_ACTIVITY_CLEAR_TOP
具有此标记的Activity在同一任务栈所有位于他上面的Activity都会被清除栈内一般与singTask一同出现,singTask默认具有此效果Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有此标记的Activity在任务栏中看不到记录