观察Activity四种启动模式在Task中的实际压栈情况

  • 首先,介绍一下设置Activity的启动模式的方法之一,在Androidmainfest.xml中的标签中配置
<activity android:name=".ThirdActivity"
            android:configChanges="orientation|screenSize"
            android:launchMode="standard/singleTop/singleTask/singleInstance">
        </activity>

launchMode后面的启动方式四选一

  • 第二,在控制台查看模拟器的堆栈情况
    打开控制台,输入:
adb shell dumpsys activity
//键入回车即可看到控制台信息

如果出现:adb: command not found则是由于没有配置环境变量导致的。
打开AS新建三个Activity[MainActivity/SecondActivity/ThirdActivity]
【1】standard:标准模式
(1)将三个Activity的启动模式都更改为“standard”(其实这一步没必要修改,activity的默认启动模式就是standard,为了有仪式感就修改一下吧)

<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="orientation|screenSize"
            android:launchMode="standard">
        </activity>
        <activity android:name=".ThirdActivity"
            android:configChanges="orientation|screenSize"
            android:launchMode="standard">
        </activity>

(2)为每个Activity设置一个Button,以下是每个activity的逻辑部分

//MainActivity
Button btFirst = (Button) findViewById(R.id.bt_first);

        btFirst.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this,SecondActivity.class));
            }
        });

//SecondActivity
Button btSecond = (Button) findViewById(R.id.bt_second);

        btSecond.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(SecondActivity.this,ThirdActivity.class));
            }
        });

逻辑很简单,打开模拟器并部署项目
然后点击第一个Activity中的按钮跳转到第二个Activity,然后再跳转到第三个Activity
以下用A,B,C分别代表MainActivity,SecondActivity,ThirdActivity
这样相当于系统创建了创建了三个Activity的实例并将它们入栈
理论上压栈情况应该为这样:

C
B
A

接下来打开控制台输入:adb shell dumpsys activity
在偏下方位置就可以看到如下信息:
在这里插入图片描述
观察控制台便可发现,情况和我们预期的一样。图片中的后台任务栈中的实例就是Android桌面

【2】singleTop:栈顶复用模式

  • 将C的启动模式改为singleTop模式

  • 启动顺序为:A—>B—>C—>C(C—>C表示C自己启动自己,就是在C中添加一个Button,监听事件写为自己启动自己)

     btThird.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             startActivity(new Intent(ThirdActivity.this,ThirdActivity.class));
         }
     });`
    

重新部署程序,返回控制台输入:adb shell dumpsys activity

可以观察到此时栈中的情况为:

Task195C
Task195B
Task195A

系统并没有再创建一个C的实例,而是直接使用栈顶的启动模式为singleTop的C

  • 再将B的启动模式也设置为singleTop
  • 启动顺序为:A—>B—>C—>B(将C中Button的逻辑改为跳转到B)
  • 控制台:adb shell dumpsys activity
    在这里插入图片描述
    可以观察到此时栈中的情况为:
Task196B
Task196C
Task196B
Task196A

意料之中的事情是不是,,,

A—>B虽然B为singleTop模式,栈顶不存在B,B入栈
B—>C和上面一样,栈顶为B,而非C。B和C都是singleTop,C入栈
C—>B此时栈顶为C,而非B,创建B的新的实例,新B入栈

【3】singleTask:栈内复用模式

  • 将A、B、C的启动模式分别修改为
Astandard
BsingleTask
Cstandard
  • 启动顺序为:A—>B—>C—>B(跳转逻辑和上一个一样,不用做修改)
  • 控制台:adb shell dumpsys activity
    在这里插入图片描述
    此时栈中的情况为:
Task197B
Task197A

出问题了,C不见了(黑人脸问号???)

A部署项目,A入栈
A—>B此时栈内没有B,创建B的实例,B入栈
B—>CC为标准模式,创建C的实例,C入栈
C—>B分析在下面表格
C到B的过程中:!!!B为栈内复用模式,B的实例已经在栈内,系统并不会创建新的实例,但此时B又需要回到栈顶,并且栈为“后进先出”,所以怎么办呢?只能是C出栈了。C出栈之后,栈内情况就为AB

【4】singleInstance:单实例模式

  • 将A、B、C的启动模式修改为:
Astandard
BsingleInstance
CsingleInstance
  • 启动模式:A—>B—>C
  • 控制台:adb shell dumpsys activity
    在这里插入图片描述
    此时栈内情况为:
Task202C
Task201B
Task200A

分析:
A在系统的前台任务栈中;
A启动了singleInstance模式的B,系统为B新创建了一个栈Task201;
B又启动了singleInstance模式的C,系统又为C新创建了一个栈Task202
因此,它们三出了A在系统前台任务栈中,B和C都分别住在系统新创建的栈中。

  • 将A、B、C的启动模式修改为
Astandard
BsingleInstance
Cstandard
  • 启动顺序:A—>B—>C
  • 控制台(…)
    在这里插入图片描述
    此时的栈的情况又为:
Task198C
Task198A
Task199B

A、C同位于系统前台任务栈,singleInstance启动模式的B在系统新创建的Task199栈中

终于深刻的理解了这四种启动模式了!呼~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值