Android的4种启动模式

启动模式简介:

1. standard:

每次启动都会创建一个新的实例,一个任务栈可以有多个实例,每个实例也可以属于不同的任务栈

2. singleTop:

栈顶复用。如果活动在栈顶,再次想创建该活动,不会创建新的Activity,同时会回调onNewIntent,通过该函数可以获得请求的信息

3. singleTask:

栈内复用,这是一种单例模式。只要Activity在一个栈中存在,多次调用都不会重新创建实例,也会回调onNewIntent,分5种情况

a) 目前任务栈S1中有ABC,这个时候Activity  D以singleTask模式请求启动,其所需要的任务栈为S2,由于S2和D的实例都不存在,所以先创建任务栈S2,然后再创建D的实例并将其入栈到S2,S1此时为ABC,S2为D

b) 目前任务栈S1中有ABC,D以singleTask模式请求启动,其所需要的任务栈为S1,由于S1已经存在,所以直接创建D的实例并将其入栈到S1,S1此时为ABCD

c) 目前任务栈S1中有ADBC,D以singleTask模式请求启动,其所需要的任务栈为S1,根据复用原则B和C出栈,D位于栈顶,此时S1为AD

4. singleInstance:

单实例模式。全局单例,当以singleInstance模式创建一个Activity时,会单独创建一个任务栈,然后在该任务栈中创建该Activity,该任务栈只能存在一个Activity

3个例子

3个Activity,分别为A、B、C

1.  A为standard,B、C为singleTask

同时设置B、C的任务栈为com.example.sun.task1,A在默认任务栈

设默认任务栈为S1,设com.example.sun.task为S2

        <activity android:name=".A">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".B"
            android:taskAffinity="com.example.sun.task1"
            android:launchMode="singleTask"/>
        <activity android:name=".C"
            android:taskAffinity="com.example.sun.task1"
            android:launchMode="singleTask"/>

启动顺序:A → B → C → A → B

退出顺序:B → A → 桌面(按两次返回键)

a)  A → B → C:

启动A:A的taskAffinity继承自包名,创建默认任务栈(即S1),然后将在S1中创建A,S1为前台任务栈

启动B:根据singleTask的启动原则a点,因为没有任务栈S2,创建任务栈S2,然后创建B,

             此时有两个任务栈S1,S2。因为此时运行B,S2为前台任务栈。

启动C:根据singleTask的启动原则b点,因为存在任务栈S2,直接创建任务栈S2,然后创建 C,

             此时有两个任务栈S1,S2。因为此时运行C,S2为前台任务栈。如下图所示

在terminal输入adb shell dumpsys activity,找到Running activities

可以看到C,B在com.example.sun.task1(即S2)中,A在com.example.sun.webtest(即S1)中,其他不用管

b)  A → B → C → A:

再启动A,因为是C启动A,并且A为standard,会把A创建在C的任务栈中,并位于栈顶

c)  A → B → C → A → B:

从A中启动B,因为B为singleTask,不会创建新的实例,根据singleTask的原则c点,把A、C出栈

 

d) 退出顺序:B → A → 桌面

此时再按返回,B从S2中出栈,S2任务栈不存在了,此时只能切换到后台任务栈S1,显示A,

再次按返回键,A从从S1中出栈,就回到了桌面

2.  A、B、C为singleTask

同时设置A的任务栈为com.example.sun.task1,BC的任务栈为com.example.sun.task2

设com.example.sun.task1任务栈为S1,com.example.sun.task2任务栈为S2

        <activity android:name=".A"
            android:taskAffinity="com.example.sun.task1"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".B"
            android:taskAffinity="com.example.sun.task2"
            android:launchMode="singleTask"/>
        <activity android:name=".C"
            android:taskAffinity="com.example.sun.task2"
            android:launchMode="singleTask"/>

启动顺序:A → B → C → A → B

退出顺序:B → A → 桌面(按两次返回键)

这里结果是和上面一样的,但任务栈的内容不一样,因为A为singleTask,具体分析如下:

 

a)  A → B → C:(基本和前面一样)

 

启动A:根据singleTask的启动原则a点,因为没有任务栈S1,创建任务栈S1,然后将在S1中创建A,S1为前台任务栈,

 

启动B:根据singleTask的启动原则a点,因为没有任务栈S2,创建任务栈S2,然后创建B,

 

             此时有两个任务栈S1,S2。因为此时运行B,S2为前台任务栈。

 

启动C:根据singleTask的启动原则b点,因为存在任务栈S2,直接创建任务栈S2,然后创建 C,

 

             此时有两个任务栈S1,S2。因为此时运行B,S2为前台任务栈,如下图所示

 

 

 

b)  A → B → C → A:

 

再启动A,因为A为singleTask,不会把A创建在C的任务栈中,而是切换S1为前台任务,S2变为后台任务

 

    

 

c)  A → B → C → A → B:

 

启动B,因为B为singleTask,根据singleTask的原则c点,把C出栈,同时S1变为后台任务,S2变为前台任务

 

 

d) 退出顺序:B → A → 桌面(按两次返回键)

 

此时再按返回,B从S2中出栈,S2任务栈不存在了,此时只能切换到后台任务栈S1,显示A,

再次按返回键,A从从S1中出栈,就回到了桌面

 

 

3. A为standard,B、C为singleInstance

此时会有3个任务栈,默认任务栈设为S1,因为singleInstance会创建独立的任务栈,不用设置taskAffinity,设置B在的任务栈为S2, C在的任务栈为S3

        <activity android:name=".A"
            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=".B"
            android:launchMode="singleInstance"/>
        <activity android:name=".C"
            android:launchMode="singleInstance"/>
 

启动流程:A → B → C → A → B

退出顺序:B → A → A → C → 桌面(按4次返回键)

 

 

a)  A → B → C:

 

 

启动A:A的taskAffinity继承自包名,创建默认任务栈(即S1),然后将在S1中创建A,S1为前台任务栈

 

 

启动B:创建一个新的任务栈(设为S2),在S2中创建B

 

 

启动C:创建一个新的任务栈(设为S3),在S2中创建C

 

 

 

b)  A → B → C → A:

 

再启动A,因为C为singleInstance,S3任务栈只会放活动C,并且A是standard,不会创建新的任务栈,所以此时切换到默认任务栈S1,并新建一个A添加到S1。图二中两个A虽然看起来不在一起,但是他们的栈号都为304

 

 

 

 

c)  A → B → C → A → B:

 

 

启动B,因为B为singleInstance,此时S2变为前台任务栈

 

 

 

 

d) 退出顺序:B → A → A → C → 桌面

 

 

此时再按返回,B从S2中出栈,S2任务栈不存在了,此时只能切换到后台任务栈S1,显示最上面的A(设为A1,下面的A设为A2),

 

 

再次按返回键A1从S1出栈,显示A2

 

 

再次按返回键A2从S1出栈,S1任务栈不存在了,S3变为前台任务,显示C

 

 

再次按返回键C从S3出栈,退回到桌面

 

 

    

 

PS

1. 如果例子2中,设置了A第一次启动B,第二启动C,即A → B → C → A → C,此时退出顺序为C → B → A,因为从A启动C 后,C在S2的栈顶,直接将前台任务切换到S2,不会将任何活动出栈

2. startActivityForResult所启动的活动的启动模式不能是singleInstance和singleTask,则onActivityResult()便立刻被回调了,且resultCode值为RESULT_CANCEL。

singleTask的原因如上一点,因为下一个返回的活动可能是其他活动,同时如果启动的活动为singleTask并且在该任务栈的底部,会把调用startActivityForResult的活动清出任务栈

singleInstance,不清楚为啥,可能不同任务栈的原因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值