深入理解Activity -动手写实例来感受Activity的启动模式

介绍

上篇提到了Activity的任务,任务栈,以及启动模式。对这些概念有了了解以后,自己写一下例子来感受一下,就当作复习和加深印象了。如果对概念不熟悉的可以参考:深入理解Activity-任务,回退栈,启动模式。

standard(标准模式)

1、概念

前面我们已经提到过,这是系统默认的模式,我们如果不在AndroidManifest.xml的Activity中制定launchMode属性,默认就是这种模式,谁启动了该模式的activity,一个该activity的实例就会被放置到谁的任务栈中。

2、例子

这个例子很简单,我们新建一个名为FirstActivity的Activity,然后放一个Button,当点击Button的时候启动自己。并且在onCreate方法中log打印出当前任务的id,代码如下:

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        Log.d("taskId", "taskId is :" + getTaskId());
    }

    public void click(View view) {
        Intent intent = new Intent(this, FirstActivity.class);
        startActivity(intent);
    }

}

运行之后我们点击6次按钮,查看log信息如下:

10-20 12:35:54.380    1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2
10-20 12:36:32.705    1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2
10-20 12:36:40.389    1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2
10-20 12:36:43.581    1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2
10-20 12:36:44.885    1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2
10-20 12:36:46.965    1949-1949/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :2

可以看到taskId都为2,说明我们的FirstActivity实例都在一个任务栈中,这个任务栈中是否的确有6个实例呢,我们在终端输入命令:adb shell dumpsys activity,执行后会出现很多信息,具体看下图:
这里写图片描述
可以看到正在运行的Activity有6个FirstActivity,由于我用MainActivity作为入口,所以还有一个MainActivity。此时处于resume状态的也是FirstActivity。到这里标准模式相信大家已经熟悉得不能再熟悉了。
关于adb的配置可以参考在Mac上配置Android adb命令

singleTop(栈顶复用模式)

1、概念

如果一个activity已经存在于一个任务栈中,那么系统就不会创建一个该activity的新实例,而是使用栈顶的activity实例,并且调用该activity的onNewIntent()的方法。

2、例子

我们新建一个名为A、B、C、三个Activity,修改C的启动模式为singleTop,第一次启动顺序为A->B->C->C。第二次我们启动顺序为A->B->C->A->C,也在onCreate方法中log打印出当前任务的id。
在执行了A->B->C->C之后我又点击了两次即A->B->C->C->C->C,log信息输出如下:

10-20 13:18:18.381  12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :3
10-20 13:18:26.701  12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :3
10-20 13:18:29.565  12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :3
10-20 13:18:32.741  12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ onNewIntent execute
10-20 13:18:59.021  12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ onNewIntent execute
10-20 13:18:59.729  12973-12973/com.example.yangqiangyu.launchmode D/taskId﹕ onNewIntent execute

可以看到的确是执行了onNewIntent方法

此时我们执行adb shell dumpsys activity以后查看任务栈中的Activity信息:
这里写图片描述
很显然虽然我们点击了多次跳转CActivity,但是由于在栈顶,所以复用了。

接下来看第二种情况A->B->C->A->C的log信息:

10-20 13:25:24.733  15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4
10-20 13:25:31.229  15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4
10-20 13:25:32.261  15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4
10-20 13:25:34.181  15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4
10-20 13:25:35.733  15426-15426/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :4

完全没有调用onNewIntent方法。

那么执行命令adb shell dumpsys activity查看一下任务栈中的信息:这里写图片描述
上面的信息说明了当不在栈顶的时候,依然会创建新的实例.

singleTask(栈内复用模式)

1、概念

如果一个activity存在于任务栈中,那么系统会使用该实例并且调用它的onNewIntent() 方法,这种模式下在一个任务中只能有一个实例。启动一个带有该模式的Activity,系统会寻找该Activity所需的任务栈,如果存在就寻找栈中有没有该Activity的实例,有就复用。没有就新建一个实例压入栈中。而如果没有Activity所需的任务栈,系统就会新建一个任务栈,然后新建一个实例压入栈中。

2、例子

我们在上面的例子上多新建出一个DActivity并设置其launchMode为singleTask,第一次启动顺序为:A->B->D->D,第二次我们启动顺序为:A->B->D->C->D。
当启动顺序为A->B->D->D的log和任务栈的信息如下:
log信息:

10-21 02:17:57.929    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :7
10-21 02:18:01.581    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :7
10-21 02:18:02.945    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :7
10-21 02:18:04.481    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ DActivity onNewIntent execute
10-21 02:18:05.389    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ DActivity onNewIntent execute

任务栈信息:
这里写图片描述

而当启动顺序为A->B->D->C->D的log和任务栈的信息如下:
log信息

10-21 02:21:04.629    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :8
10-21 02:21:11.621    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :8
10-21 02:21:13.213    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :8
10-21 02:21:14.869    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :8
10-21 02:21:17.189    5545-5545/com.example.yangqiangyu.launchmode D/taskId﹕ DActivity onNewIntent execute

任务栈信息:
这里写图片描述

很明显singleTask模式只要栈中存在,就复用,调用onNewIntent方法。而对应于第二种情况,由于要复用栈中的D,所以必需先让C出栈。所有栈内由顶向下是D->B->A。当我们finish的时候就会直接到B了。

####3、TaskAffinity
在singleTask种,该参数表示一个Activity所需要的任务栈的名字,默认情况所有的Activity所需的任务栈的名字为应用的包名。 我们在上面例子中的DActivity配置 android:taskAffinity=“com.example.yangqiangyu.launchmode2”。然然后启动A->B->D,log信息如下:

10-21 02:34:34.053  15657-15657/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :9
10-21 02:34:42.513  15657-15657/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :9
10-21 02:34:44.437  15657-15657/com.example.yangqiangyu.launchmode D/taskId﹕ taskId is :10

可以看到DActivity的taskId和之前的不一样,说明它在另外一个任务栈中.

singleInstance

这个模式除了拥有singleTask的所有特点外,在该模式下的activity实只能单独的在一个任务栈中。这里就不写例子测试了

例子源码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员yqy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值