美文网首页
Android初级开发笔记-- Activity启动模式的学习(

Android初级开发笔记-- Activity启动模式的学习(

作者: 8e750c8f0fae | 来源:发表于2019-07-08 00:57 被阅读0次

    在上篇文章中已经介绍了和启动模式相关的基础知识,想了解的小伙伴可以戳下方链接:https://blog.csdn.net/qq_42171948/article/details/90168514

    在对activity四种启动模式有所理解之后。这篇文章将会继续解决上篇所留下的问题
    1.如何设置不同的任务栈?
    2.当activityA以标准模式启动B的时候,B的实例被创建且处于activityA任务栈的顶端,那么这个时候B启动了A(standard)呢?
    3.这两种设置方式有什么区别呢?常用的标志位有好几个,组合起来使用又有什么不同的效果呢?

    我们知道,默认情况下,所有activity都运行在同一个任务栈中,此栈名为<manifest> 元素设置的软件包名称。那么如何设置不同的任务栈,很简单,用taskAffinity。

    taskAffinity

    taskAffinity是一个表明activity想在哪个任务栈的参数。在manifest里面可以进行设置。

       <activity android:name=".MainActivity"
                android:taskAffinity="com.example.administrator.test">
    
    • 每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。默认是包名。
    • 每个task有affinity属性,等于它的根 Activity的taskAffinity的值。
    • 在不设置其他的前提下,经检验,只有在singleTask,和singleInstance模式中,taskAffinity才会起到应有的作用。
      贴上代码:
      当两个activity的taskAffinity不一样时:
      manifest:
     <activity android:name=".MainActivity"
                android:taskAffinity="com.example.administrator.test">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".MainActivity2"
                android:launchMode="singleTask"
                android:taskAffinity="com.example.administrator.test1">
            </activity>
    

    mainactivity:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView show = (TextView) findViewById(R.id.tv_show);
    
            show.setText(this.toString() + "\ntaskId:" + this.getTaskId());
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            Log.e("task", "intent1=" + intent);
        }
    
        public void jump(View v) {
            Intent intent = new Intent(this,MainActivity2.class);
            startActivity(intent);
        }
    }
    

    mainactivity2:

    public class MainActivity2 extends AppCompatActivity{
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
            TextView show = (TextView) findViewById(R.id.tv_show);
    
            show.setText(this.toString() + "\ntaskId:" + this.getTaskId());
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            Log.e("task","intent2"+intent);
        }
    }
    

    现象是:


    1.png
    2.png

    当两个activity的taskAffinity一样时:


    3.png
    4.png

    由此可以得出结论:
    以1启动2来说
    (1) 当1和2的taskAffinity相同时:当第一次创建2 的实例时,并不会创建新的task,乃是将在1的task中创建2的实例;当1的task已经存在2的实例时,此时启动2,则会检查一下task中是否有2实例,然后将2上的其他实例出栈,将2实例置于栈顶,从而实现了跳转。
    (2) 当1和2的taskAffinity不同时:当第一次创建2 的实例时,将会创建新的task,在指定的task中创建2的实例;当指定task已经存在2的实例时,此时启动2,则会检查一下task中是否有2实例,然后将2上的其他实例出栈,将2实例置于栈顶,从而实现了跳转。

    说了这么多,其实就是很简单的一句话,taskAffinity设置新启动的activity应处于哪个task,一种是在创建它的activity所处栈,一种是新栈,其他的分析就是对singleTask的理解而已。

    另外,文档给我们提供了一种会出现:本来在某一个Task中,之后出现了转移的情况。
    如果该Activity的allowTaskReparenting属性设置为true,当启动它的任务栈进入后台,一个和它有相同affinity的Task进入前台时,该Activity会进入到该前台的task中。
    (以下是翻译)
    例子是,如果电子邮件包含网页链接,则点击链接会调出可显示网页的 Activity。 该 Activity 由浏览器应用定义,但作为电子邮件任务的一部分启动。 如果将其父项更改为浏览器任务,它会在浏览器下一次转至前台时显示,当电子邮件任务再次转至前台时则会消失。
    我的理解:当一个应用A启动了应用B的某个ActivityC后(C的taskAffinity 为B),如果我们将ActivityC的allowTaskReparenting属性设置为true,当应用B被启动后,系统会发现Activity C所需的任务栈已经存在,ActivityC就会从A的任务栈转移到B的任务栈中。
    (以下还是翻译)
    Activity 的亲和关系由 taskAffinity 属性定义。 任务的亲和关系通过读取其根 Activity 的亲和关系来确定。因此,按照定义,根 Activity 始终位于具有相同亲和关系的任务之中。 由于具有“singleTask”或“singleInstance”启动模式的 Activity 只能位于任务的根,因此更改父项仅限于“standard”和“singleTop”模式。
    我的理解: 每个task有affinity属性,等于它的根 Activity的taskAffinity的值。singletask和singleinstance模式下,Atask中只能有一个A实例,且为根,那么就不能重新宿主,要不然的话这个栈就崩了呢~而另外两种的话,因为不是根所以可以在特定情境下自由游荡。

    写在最后

    由于篇幅和时间关系,文章就到此结束,剩下的问题待Android初级开发笔记-- activity启动模式的学习(3)再进行讨论~

    相关文章

      网友评论

          本文标题:Android初级开发笔记-- Activity启动模式的学习(

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