美文网首页
Activity四种启动模式

Activity四种启动模式

作者: 四喜汤圆 | 来源:发表于2018-04-23 20:44 被阅读2次

    一、四种启动模式详细介绍

    以下内容完全摘抄自小路飞_掘金

    介绍 Android 启动模式之前,先介绍两个概念task和taskAffinity

    • task:翻译过来就是“任务”,是一组相互有关联的 activity 集合,可以理解为 Activity 是在 task 里面活动的。 task 存在于一个称为 back stack 的数据结构中,也就是说, task 是以栈的形式去管理 activity 的,所以也叫可以称为“任务栈”。
    • taskAffinity:官方文档解释是:"The task that the activity has an affinity for.",可以翻译为 activity 相关或者亲和的任务,这个参数标识了一个 Activity 所需要的任务栈的名字。默认情况下,所有Activity所需的任务栈的名字为应用的包名。 taskAffinity 属性主要和 singleTask 启动模式或者 allowTaskReparenting 属性配对使用。

    4种启动模式

    1. standard:标准模式,也是系统默认的启动模式。假如 activity A 启动了 activity B , activity B 则会运行在 activity A 所在的任务栈中。而且每次启动一个 Activity ,都会重新创建新的实例,不管这个实例在任务中是否已经存在。非 Activity 类型的 context (如 ApplicationContext )启动 standard 模式的 Activity 时会报错。非 Activity 类型的 context 并没有所谓的任务栈,由于上面第 1 点的原因所以系统会报错。此解决办法就是为待启动 Activity 指定 FLAG_ACTIVITY_NEW_TASK 标记位,这样启动的时候系统就会为它创建一个新的任务栈。这个时候待启动 Activity 其实是以 singleTask 模式启动的。
    2. singleTop:栈顶复用模式。假如 activity A 启动了 activity B ,就会判断 A 所在的任务栈栈顶是否是 B 的实例。如果是,则不创建新的 activity B 实例而是直接引用这个栈顶实例,同时 onNewIntent 方法会被回调,通过该方法的参数可以取得当前请求的信息;如果不是,则创建新的 activity B 实例。
    3. singleTask:栈内复用模式。在第一次启动这个 Activity 时,系统便会创建一个新的任务,并且初始化 Activity 的实例,放在新任务的底部。不过需要满足一定条件的。那就是需要设置 taskAffinity 属性。前面也说过了, taskAffinity 属性是和 singleTask 模式搭配使用的。
    image
    1. singleInstance:单实例模式。这个是 singleTask 模式的加强版,它除了具有 singleTask 模式的所有特性外,它还有一点独特的特性,那就是此模式的 Activity 只能单独地位于一个任务栈,不与其他 Activity 共存于同一个任务栈。

    二、重点说明

    1. android:taskAffinity属性

    singleTask一般和taskAffinity属性搭配使用

    每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的属性就等于Application指明的taskAffinity。如果Application也没有指明,那么该taskAffinity的值就等于包名

    只要知道这个Activity是以哪种启动模式启动的(可能在AndroidManifest中指定,也可能在代码中指定),再根据上述规则,就能指定它要进入的是哪个任务栈

    举例说明:FirstActivity.class中点击按钮启动SecondActivity.class

    /**
     * <pre>
     *     author : 杨丽金
     *     time   : 2018/04/23
     *     desc   :
     * </pre>
     */
    public class FirstActivity extends BaseActivity {
        @BindView(R.id.btn_jump)
        Button btn_jump;
    
        @Override
        public int getLayoutId() {
            return R.layout.activity_first;
        }
    
        @Override
        public void initData(Bundle savedInstanceState) {
    
        }
    
        @Override
        public void setListener() {
            btn_jump.setOnClickListener(new View.OnClickListener(){
    
                @Override
                public void onClick(View v) {
                    // 启动SecondActivity,以singleTask模式启动,该模式和taskAffinity属性搭配使用
                    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
            });
        }
    
    }
    
    1. 当SecondActivity在清单文件中的配置如下时:
      以SingleTask模式启动的SecondActivity,和FirstActivity在不同任务栈中

           <activity android:name=".module.startmode.FirstActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
            <!--该配置表示:1,通过正常方式启动该Activity,该Activity就会在原有任务栈中启动(启动该Activity的任务栈)
                2,若想要taskAffinity属性生效,需要在启动Activity时设置Flag为FLAG_ACTIVITY_NEW_TASK-->
            <activity android:name=".module.startmode.SecondActivity"
                android:taskAffinity="com.whut.ylj"/>
    
    1. 当SecondActivity在清单文件中的配置如下时:
      以SingleTask模式启动的SecondActivity,和FirstActivity在同一任务栈中

            <activity android:name=".module.startmode.FirstActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
            <activity android:name=".module.startmode.SecondActivity"/>
    

    2.onNewIntent()

    当Activity的启动模式设置为sinleTop、singleTask时,如果Activity栈中有该Activity,想要再次打开Activity时,Activity不会重新创建,只会回调该方法。

    @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
        }
    

    参考文献

    Taskaffinity属性使用小结

    相关文章

      网友评论

          本文标题:Activity四种启动模式

          本文链接:https://www.haomeiwen.com/subject/kdfrlftx.html