• 【activity任务栈】浅析


    背景知识

    Activity四种启动模式

    • 标准模式 standard
    • 栈顶复用模式 singleTop
    • 栈内复用模式 singleTask
    • 单例模式 singleInstance

    任务栈

    Activity的Flags

    Activity的Flags很多,这里介绍集中常用的,用于设定Activity的启动模式。可以在启动Activity时,通过Intent的addFlags()方法设置。

    (1)FLAG_ACTIVITY_NEW_TASK 其效果与指定Activity为singleTask模式一致。

    (2)FLAG_ACTIVITY_SINGLE_TOP 其效果与指定Activity为singleTop模式一致。

    (3)FLAG_ACTIVITY_CLEAR_TOP 具有此标记位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。如果和singleTask模式一起出现,若被启动的Activity已经存在栈中,则清除其之上的Activity,并调用该Activity的onNewIntent方法。如果被启动的Activity采用standard模式,那么该Activity连同之上的所有Activity出栈,然后创建新的Activity实例并压入栈中。

    四种启动模式的基础功能就不再赘述;

    问题:

    (1)如果在Service或Application中启动一个Activity,其并没有所谓的任务栈,怎么实现?

    • 可以使用标记位Flag来解决。解决办法:为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位,创建一个新栈。

    (2)除了singleInsatance模式,有没有其他方法使activity独立一个栈?

    • 待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位,就会创建一个新栈。

    (3)何时调用onNewIntent()方法?

    • Activity已经启动过,处于Acrtivity栈中
    • 当launchMode为singleTop时,如果在栈顶,再次启动会调用
    • 当launchMode为singleTask、singleInstance时,如果已经在Activity栈内,再次启动会调用onNewIntent()方法
    • 当launchMode为standard时,不会调用

    (4)打开a、b、c后在c中如何关闭a、b

    (5)其他:

    1. setResult()必须在finish()之前调用
    2. 多任务栈的情况下,setResult后,前Activity均能拿到消息
    3. ActivityA(standard)-->ActivityB(singleInstance)-->ActivityC(standard)

      此时按back键ActivityC-->ActivityA-->ActivityB

      public class ActivityA extends Activity {//activity代码、b、c基本相同
          private static final String ACTIVITY_NAME = "ActivityA";
          private static final String LOG_TAG = "test_activity_stack";
      
          @Override
          protected void onCreate(@Nullable Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_btn);
              refreshTask();
              findViewById(R.id.btn_task).setOnClickListener(v -> startActivity(new Intent(this, ActivityB.class)));
          }
      
          @Override
          protected void onDestroy() {
              super.onDestroy();
              refreshTask();
          }
      
          private void refreshTask() {
              int taskId = getTaskId();
              Log.i(LOG_TAG, ACTIVITY_NAME + "所在的任务的id为: " + taskId);
              ((TextView) findViewById(R.id.tv_task)).setText(LOG_TAG + "  " + ACTIVITY_NAME + "所在的任务的id为: " + taskId);
          }
      }

      如上图三个Activity分别设置standard、singleInstance、standard;运行起来的结果

      可以看到,A在任务栈4973启动B,启动了一个任务栈4974;启动C又回到了4973;

      以此点击back键退出

      首先从C回到A,再之后回到4974任务栈的B(如果A、C所在的4973仍有其他activity,会一直退到栈空才会回到B)

    4. startActivityForResult打开单独进程的Acitivity,启动模式将不起作用。在情况3中,按back键ActivityC-->ActivityB-->ActivityA,两任务在同一任务栈中;换言之,进程与任务栈没有必然关系
  • 相关阅读:
    终于看到费德勒在法网如愿!
    o(∩_∩)o...,今天去博客园了!
    条款4:使用Conditional特性代替#if条件编译
    MSDTC无法启动的解决方法
    2009 很有意义的一天
    从现在开始,争取记录每天所学到的、所感受到的、所遇见到的点点滴滴!
    了解MOSS2007 内容类型ID(Content Type IDs)命名规则
    CreateSpecificCulture('zhcn')和new CultureInfo('zhcn')的区别
    金华大显数码科技有限公司诚聘
    使用SQL Server中按位于来表示组合状态
  • 原文地址:https://www.cnblogs.com/ivoo/p/10727289.html
Copyright © 2020-2023  润新知