精华内容
下载资源
问答
  • 2020-10-26 16:51:01

    1. Activity启动模式singleTask的理解

    2. Task与Activity栈

    Task是一些Activity的集合,以Activity栈的形式存放。因此,Task是概念上的,Activity栈是实体上的。

    可以说,新启动了一个Task就是新建了一个Activity栈,来存放这个Task内的Activity。

    3. singleTask设置方式

    • manifest文件
      在activity节点里添加属性:
    <activity
        android:name="com.example.test.SecondActivity"
        android:launchMode="singleTask"
    />
    
    
    • intent设置FLAG
    Intent intent = new Intent(this, SecondActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
    

    4. singleTask的意义(作用)

    把一个activity启动模式设置为为singleTask,只是意味着framework在启动该activity时把它标识为可在一个新任务中启动,至于是否在一个新任务中启动,那可不一定了!是需要条件的,什么条件呢?请看下文分解~

    4.1. 举例说明

    4.2. 例子1

    假设下面的跳转关系:

    MainActivity -> SecondeActivity -> ThirdActivity

    其中,SecondeActivity被设置了singleTask的启动模式,MainActivity和ThirdActivity都不做任何操作,保持默认,即standard模式

    那么跳到ThirdActivity后,当前的Activity栈情况从顶到底部是:

    ThirdActivity、SecondeActivity、MainActivity

    也就是说依然按照正常压栈的顺序,和standard模式一样。并不是按照谷歌官方解释的,容易误解为新建了一个Task,并用新的栈存放SecondeActivity。这是误解。

    那么,真的和standard模式一样吗?

    还是有不同的,不然弄这个模式干嘛。

    不同之处,用下面的例子说明:

    4.3. 例子2

    假设下面的跳转关系:

    MainActivity -> SecondeActivity -> ThirdActivity -> ForthActivity ->SecondeActivity

    其中,SecondeActivity被设置了singleTask的启动模式,其余Activity都不做任何操作,保持默认,即standard模式

    那么跳到SecondeActivity后,当前的Activity栈情况从顶到底部是:

    SecondeActivity、MainActivity

    没错,SecondeActivity以上的 ThirdActivity、ForthActivity都被销毁了。

    也就是说,重用了栈里面已有的 SecondeActivity ,并且把它上面的 activity 都清除了,从而使得它暴露在最上面。

    顺便说一下,最后一个SecondeActivity的启动没有调用onCreate,而是依次调用了onRestart、onStart、onNewIntent、onResume这些生命周期方法。

    4.4. 小结

    被标记为singleTask的Activity,在启动的时候如果当前没有实例,就和standard模式一样,直接压栈到当前activity上;如果已经有实例了,就把该目标Activity实例上面的activity都清除,从而将目标Activity暴露到最上面,调用了其onNewIntent方法

    5. taskAffinity属性

    上面的两个例子都在我们认知范围内,还比较熟悉。但是这个taskAffinity想必就不太熟悉了。

    taskAffinity是标记当前activity附属到哪个task上的。

    5.1. 配置方式

    • manifest文件里
      在activty节点里配置该属性即可。taskAffinity取值是一个字符串,用来唯一标识一个Task的。

    默认情况下,也就是不配置,taskAffinity取的是应用的包名。

     <activity android:name="com.example.test.SecondActivity"
                 android:launchMode="singleTask"
                 android:taskAffinity="com.example.test.second">
            </activity>
    

    5.2. 意义(作用)

    配合singleTask使用,意味着被这两个属性标记的activity可以被指定到一个新的task里。

    5.3. 举例

    假设下面的跳转关系:

    MainActivity -> SecondeActivity -> ThirdActivity

    其中,SecondeActivity被设置了singleTask的启动模式,并且配置了taskAffinity属性,MainActivity和ThirdActivity都不做任何操作,保持默认,即standard模式

    那么跳到ThirdActivity后,当前的Activity栈情况从顶到底部是:

    Task1: ThirdActivity、MainActivity

    Task2: SecondeActivity

    可以看到,SecondeActivity被创建到了新的栈里。

    于是,可以得出之前疑问的答案,什么条件下设置为singleTask的activity会被创建到新的task呢?

    答案是,同时被指定了另一个taskAffinity属性值的时候。

    5.4. 回退顺序

    现在处于onResume的activity是ThirdActivity,如果这时候按返回键呢?activity的显示顺序会是什么样呢?

    答案正如上面Task1、Task2栈的排列顺序,ThirdActivity弹出后,MainActivity显示;再按返回键,MainActivity弹出后,SecondeActivity显示。

    可以看出,新建的Task处于下方。

    5.5. 总结

    1. 把启动模式设置为singleTask,framework在启动该activity时只会把它标示为可在一个新任务中启动,至于是否在一个新任务中启动,还要受其他条件的限制,这个条件就是taskAffinity属性配置为不同于包名的其他字符串。如果没有配置,默认就是当前包名,在当前Task内操作。
    2. 在启动一个singleTask的Activity实例时,如果系统中已经存在这样一个实例,就会将这个实例调度到任务栈的栈顶,并清除它当前所在任务中位于它上面的所有的activity。
      如果不存在,就看taskAffinity属性对应的Task是否存在,如果存在,就把Activity压入该Task内栈里;否则,就新建一个Task,再把Activity压入该Task内栈里。
    3. singeTask模式保证了在一个Task内只有一个activity实例

    参考文章:https://blog.csdn.net/zhangjg_blog/article/details/10923643

    更多相关内容
  • 本文实例分析了Android Activity启动模式之singleTask。分享给大家供大家参考,具体如下: 前面的文章介绍了Android 活动Activity的启动模式:standard 和singleTop 。本文继续介绍Activity的下一个启动模式:...
  • singleTask无效 (Nubia)apk

    2015-08-21 18:03:04
    来自我的文章http://www.jianshu.com/p/71d99b8bfd5d 中的apk,关于singleTask在Nubia手机无效的问题
  • singleTask和startActivityForResult的纠葛(activity的重建/onActivityResult回调为0) 问题验证: 1.startActivityForResult打开singleTask模式的活动,singTask失效。(见Action2) 2.singleTask模式的活动...
  • NULL 博文链接:https://uuubd.iteye.com/blog/1900472
  • android singleTask

    2015-08-18 15:46:09
    android singleTask http://u.download.csdn.net/upload?ref=toolbar
  • 启动模式的重要性 Android编程中经常涉及到页面的切换,启动一个新的页面(或者说Activity)的时候需要为其指定合适的“启动模式”。指定的启动模式不合适,会出现类似下面这种奇怪的效果: ...这些情况都是我在自己写...
  • 写了一篇关于Activity启动模式的文章,这是示例代码
  • 当应用运行起来后就会开启一条线程,线程中会运行一个任务栈,当Activity实例创建后就会放入任务栈中。Activity启动模式的设置在AndroidManifest.xml文件中,通过配置Activity的属性android:launchMode=""设置
  • Android - singleTask启动模式详解

    千次阅读 2022-01-02 22:05:09
    其启动流程与singleTask相同,但实例创建方式还是遵循在Manifest文件中声明的启动模式规则。 如果使用FLAG_ACTIVITY_NEW_TASK启动的activity所属的任务栈与启动他的activity的任务栈相同,则在同一个任务栈中创建或...

    其运行日志如下:

    2021-04-04 22:45:03.650 17626-17626/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43112
    2021-04-04 22:45:14.365 17626-17626/com.example.myfirstapp I/System.out: SingleTaskActivity Create. Task Id: 43112
    2021-04-04 22:45:14.803 17626-17626/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43112

    如果当前栈中存在SingleTaskActivity的实例,则调用该实例的onNewIntent()方法,并清空任务栈中该实例之上的所有activity的实例,并将其置于栈顶。其调用图如图4所示:

    singleTask_3.png

    图4 任务栈中存在实例对象时启动SingleTaskActivity

    其运行日志如下:

    2021-04-04 22:45:03.650 17626-17626/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43112
    2021-04-04 22:45:14.365 17626-17626/com.example.myfirstapp I/System.out: SingleTaskActivity Create. Task Id: 43112
    2021-04-04 22:45:14.803 17626-17626/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43112
    2021-04-04 22:45:27.204 17626-17626/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43112
    2021-04-04 22:45:27.614 17626-17626/com.example.myfirstapp I/System.out: SingleTaskActivity Stop. Task Id: 43112
    2021-04-04 22:45:32.225 17626-17626/com.example.myfirstapp I/System.out: SingleTaskActivity onNewIntent. Task Id: 43112
    2021-04-04 22:45:32.620 17626-17626/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43112
    2021-04-04 22:45:32.621 17626-17626/com.example.myfirstapp I/System.out: MainActivity Destroy. Task Id: 43112

    2.2 启动singleTask (声明taskAffinity)

    taskAffinity表示activity在应用中所属的任务栈。

    启动应用后,系统当前任务栈如图5所示:

    singleTask_1.png

    图5 应用启动默认任务栈

    MainActivity启动SingleTaskAffinityActivity时,SingleTaskAffinityActivity所属的任务栈为**com.example.myfirstapp.a1**(见上述代码片段)。由于系统中没有该任务栈,因此系统创建一个新的任务栈,并在该任务栈中创建SingleTaskAffinityActivity的实例对象。将新建的任务栈转为前台任务栈,原先的任务栈该为在后台运行。其调用图如图6所示:

    singleTask_4.png

    图6 默认任务栈启动SingleTaskAffinityActivity并创建新任务栈

    其运行日志如下:

    2021-04-04 22:46:01.608 19083-19083/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43113
    2021-04-04 22:46:10.912 19083-19083/com.example.myfirstapp I/System.out: SingleTaskAffinityActivity Create. Task Id: 43114
    2021-04-04 22:46:11.427 19083-19083/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43113

    如果内存中存在com.example.myfirstapp.a1任务栈且其中存在SingleTaskAffinityActivity的实例对象时,MainActivity启动SingleTaskAffinityActivity,系统会调用SingleTaskAffinityActivityonNewIntent()方法并销毁com.example.myfirstapp.a1任务栈中在该实例对象之上所有的实例,并将SingleTaskAffinityActivity的实例对象置于栈顶。同时系统将com.example.myfirstapp.a1设置为前台任务栈,将原先任务栈转为后台运行。其调用图如图7所示:

    singleTask_5.png

    图7 系统存在a1任务栈且该栈中存在该实例对象时从默认任务栈启动SingleTaskAffinityActivity

    其运行日志如下:

    2021-04-04 22:46:01.608 19083-19083/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43113
    2021-04-04 22:46:10.912 19083-19083/com.example.myfirstapp I/System.out: SingleTaskAffinityActivity Create. Task Id: 43114
    2021-04-04 22:46:11.427 19083-19083/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43113
    2021-04-04 22:46:33.892 19083-19083/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43114
    2021-04-04 22:46:34.304 19083-19083/com.example.myfirstapp I/System.out: SingleTaskAffinity Stop. Task Id: 43114
    2021-04-04 22:46:48.987 19083-19083/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43114
    //以上为前期准备日志
    //以下为上图流程日志
    2021-04-04 22:46:53.976 19083-19083/com.example.myfirstapp I/System.out: MainActivity Destroy. Task Id: 43114
    2021-04-04 22:46:53.999 19083-19083/com.example.myfirstapp I/System.out: SingleTaskAffinityActivity onNewIntent. Task Id: 43114
    2021-04-04 22:46:54.567 19083-19083/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43113

    如果在其他任务栈中启动SingleTaskActivity,首先寻找系统中是否存在默认任务栈,若存在且该任务栈中不存在SingleTaskActivity实例对象,则将默认任务栈转为前台任务栈且创建SingleTaskActivity实例对象并置于栈顶。其调用图如图8所示:

    singleTask_6.png

    图8 默认任务栈中不存在实例时在其他任务栈启动SingleTaskActivity

    其运行日志如下:

    2021-04-05 22:04:41.784 32718-32718/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43226
    2021-04-05 22:04:46.692 32718-32718/com.example.myfirstapp I/System.out: SingleTaskAffinityActivity Create. Task Id: 43227
    2021-04-05 22:04:47.202 32718-32718/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43226
    //以上为前期准备日志
    //以下为上图流程日志
    2021-04-05 22:06:00.211 32718-32718/com.example.myfirstapp I/System.out: SingleTaskActivity Create. Task Id: 43226
    2021-04-05 22:06:00.832 32718-32718/com.example.myfirstapp I/System.out: SingleTaskAffinity Stop. Task Id: 43227

    如果在其他任务栈中启动SingleTaskActivity,系统中存在默认任务栈且该任务栈中存在SingleTaskActivity的实例对象,则将默认任务栈转为前台任务栈并调用SingleTaskActivity实例对象的onNewIntent()方法,销毁栈中该实例对象之上的所有实例。其调用图如图9所示:

    singleTask_7.png

    图9 默认任务栈中存在该实例时在其他任务栈启动SingleTaskActivity

    其运行日志如下:

    2021-04-05 22:17:20.479 13497-13497/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43228
    2021-04-05 22:17:28.142 13497-13497/com.example.myfirstapp I/System.out: SingleTaskActivity Create. Task Id: 43228
    2021-04-05 22:17:28.564 13497-13497/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43228
    2021-04-05 22:17:29.455 13497-13497/com.example.myfirstapp I/System.out: MainActivity Create. Task Id: 43228
    2021-04-05 22:17:29.865 13497-13497/com.example.myfirstapp I/System.out: SingleTaskActivity Stop. Task Id: 43228
    2021-04-05 22:17:38.971 13497-13497/com.example.myfirstapp I/System.out: SingleTaskAffinityActivity Create. Task Id: 43229
    2021-04-05 22:17:39.450 13497-13497/com.example.myfirstapp I/System.out: MainActivity Stop. Task Id: 43228
    //以上为前期准备日志
    //以下为上图流程日志
    2021-04-05 22:18:01.954 13497-13497/com.example.myfirstapp I/System.out: MainActivity Destroy. Task Id: 43228
    2021-04-05 22:18:01.975 13497-13497/com.example.myfirstapp I/System.out: SingleTaskActivity onNewIntent. Task Id: 43228
    2021-04-05 22:18:02.550 13497-13497/com.example.myfirstapp I/System.out: SingleTaskAffinity Stop. Task Id: 43229

    如果在其他任务栈中启动SingleTaskActivity,系统中不存在默认任务栈,则创建一个任务栈,将该任务栈置为前台任务栈并在该任务栈中创建SingleTaskActivity实例对象。其调用图如图10所示:

    singleTask_8.png

    图10 系统只存在一个任务栈时在非所属任务栈中启动SingleTaskActivity

    其运行日志如下:

    2021-04-05 22:24:22.218 23571-23571/com.example.myfirstapp I/System.out: SingleTaskAffinityActivity Create. Task Id: 43233
    2021-04-05 22:24:24.994 23571-23571/com.example.myfirstapp I/System.out: SingleTaskActivity Create. Task Id: 43234
    2021-04-05 22:24:25.482 23571-23571/com.example.myfirstapp I/System.out: SingleTaskAffinity Stop. Task Id: 43233

    2.3 使用FLAG_ACTIVITY_NEW_TASK启动

    使用FLAG_ACTIVITY_NEW_TASK启动activity时,系统通常会创建一个新的任务栈。但如果系统中已经存在该activity所属的任务栈时,该activity则会在对应任务栈中启动。其启动流程与singleTask相同,但实例创建方式还是遵循在Manifest文件中声明的启动模式规则

    如果使用FLAG_ACTIVITY_NEW_TASK启动的activity所属的任务栈与启动他的activity的任务栈相同,则在同一个任务栈中创建或复用该activity的实例对象。

    启动应用后,系统当前任务栈如图11所示:

    singleTask_1.png

    图11 应用启动默认任务栈

    MainActivity使用FLAG_ACTIVITY_NEW_TASK启动MainActivity时,由于系统已经存在MainActivity所属的任务栈且MainActivity的启动模式为standard,因此系统会在原有任务栈上创建新的MainActivity实例对象。再用新启动的MainActivity实例启动SingleTaskActivity时,流程同singleTask的启动模式相同。如图12所示:

    singleTask_9.png

    图12 MainActivity使用FLAG_ACTIVITY_NEW_TASK启动MainActivity,再使用相同flag启动SingleTaskActivity

    其运行日志如下:

    [外链图片转存中…(img-TrXyz75N-1641132290930)]

    图12 MainActivity使用FLAG_ACTIVITY_NEW_TASK启动MainActivity,再使用相同flag启动SingleTaskActivity

    其运行日志如下:

    展开全文
  • SingleTask与SingleInstance的区别,看过文档后还是不太明白,于是写了一个测试程序,运行TaskA,页面显示taskid,通过Next调出TaskB的Activity,每个页面都会显示当前的taskid,且通过页面透明叠加,可以清楚看到...
  • 现有四个Activity:...启动模式singleTask和taskAffinity属性配置以及任务栈如下 一、不配置singleTask <activity android:name=".activity.MainActivity" android:taskAffinity="com.i.designpattern"

    目录

    一、同一进程下,任务栈和singleTask/taskAffinity的关系

    1、不配置singleTask

    2、配置singleTask

    3、配置singleTask & taskAffinity不同

    二、不同应用/进程下,任务栈和singleTask/taskAffinity的关系

    1、不同taskAffinity

    2、配置singleTask,且taskAffinity也不同


    现有四个Activity:MainActivity DetailActivity Task2CActivity Task2DActivity

    现研究启动模式singleTask和taskAffinity属性和任务栈的情况

    一、同一进程下,任务栈和singleTask/taskAffinity的关系

    1、不配置singleTask

            <activity
                android:name=".activity.MainActivity"
                android:taskAffinity="com.i.designpattern" />
    
            <activity
                android:name=".activity.taskStack.DetailActivity"
                android:taskAffinity="com.i.designpattern" />
    
            <activity
                android:name=".activity.taskStack.Task2CActivity"
                android:taskAffinity="com.i.newTask" />
    
            <activity
                android:name=".activity.taskStack.Task2DActivity"
                android:taskAffinity="com.i.newTask" />

     任务栈打印情况如下:

    * Task{b8d873c #21 type=standard A=10148:com.i.designpattern U=0 visible=true mode=fullscreen translucent=false sz=4}
            bounds=[0,0][720,1280]
            * ActivityRecord{6fd80b3 u0 com.i.designpattern/.activity.taskStack.Task2DActivity t21}
            * ActivityRecord{95f8128 u0 com.i.designpattern/.activity.taskStack.Task2CActivity t21}
            * ActivityRecord{2273f74 u0 com.i.designpattern/.activity.taskStack.DetailActivity t21}
            * ActivityRecord{37978e0 u0 com.i.designpattern/.activity.MainActivity t21}

    结论1:同一进程下,不配置singleTask,taskAffinity不同,则任务栈相同(和启动activity相同)。

    2、配置singleTask

            <activity
                android:name=".activity.MainActivity"
                android:taskAffinity="com.i.designpattern" />
    
            <activity
                android:name=".activity.taskStack.DetailActivity"
                android:taskAffinity="com.i.designpattern" />
    
            <activity
                android:name=".activity.taskStack.Task2CActivity"
                android:launchMode="singleTask" />
    
            <activity
                android:name=".activity.taskStack.Task2DActivity"
                android:launchMode="singleTask" />

    任务栈打印情况如下:

    * Task{4b5972a #23 type=standard A=10148:com.i.designpattern U=0 visible=true mode=fullscreen translucent=false sz=4}
            bounds=[0,0][720,1280]
            * ActivityRecord{dbad782 u0 com.i.designpattern/.activity.taskStack.Task2DActivity t23}
            * ActivityRecord{18cd2b u0 com.i.designpattern/.activity.taskStack.Task2CActivity t23}
            * ActivityRecord{a2ef327 u0 com.i.designpattern/.activity.taskStack.DetailActivity t23}
            * ActivityRecord{38eaa22 u0 com.i.designpattern/.activity.MainActivity t23}

    结论2:同一进程下,配置singleTask(只代表一个任务栈只有一个activity),taskAffinity相同,则任务栈相同(和启动activity相同)。

    3、配置singleTask & taskAffinity不同

            <activity
                android:name=".activity.MainActivity"
                android:taskAffinity="com.i.designpattern" />
    
            <activity
                android:name=".activity.taskStack.DetailActivity"
                android:taskAffinity="com.i.designpattern"
                android:launchMode="singleTask" />
    
            <activity
                android:name=".activity.taskStack.Task2CActivity"
                android:taskAffinity="com.i.newTask"
                android:launchMode="singleTask" />
    
            <activity
                android:name=".activity.taskStack.Task2DActivity"
                android:taskAffinity="com.i.newTask" />

    任务栈打印情况如下:

    * Task{f84412f #28 type=standard A=10148:com.i.newTask U=0 visible=true mode=fullscreen translucent=false sz=2}
            bounds=[0,0][720,1280]
            * ActivityRecord{49a2f21 u0 com.i.designpattern/.activity.taskStack.Task2DActivity t28}
            * ActivityRecord{8954237 u0 com.i.designpattern/.activity.taskStack.Task2CActivity t28}
    
    * Task{85d70a2 #27 type=standard A=10148:com.i.designpattern U=0 visible=false mode=fullscreen translucent=true sz=2}
            bounds=[0,0][720,1280]
            * ActivityRecord{6e5d6f3 u0 com.i.designpattern/.activity.taskStack.DetailActivity t27}
            * ActivityRecord{14fcb89 u0 com.i.designpattern/.activity.MainActivity t27}
    

    结论3:同一进程下,配置singleTask,且taskAffinity不相同,则开启新的任务栈(任务栈名称同taskAffinity值)。

    二、不同应用/进程下,任务栈和singleTask/taskAffinity的关系

    1、不同taskAffinity

    //A应用     
            <activity
                android:name=".activity.MainActivity"
                android:taskAffinity="com.i.designpattern" />
    
            <activity
                android:name=".activity.taskStack.DetailActivity"
                android:taskAffinity="com.i.designpattern" />
    
    //B应用
    
            <activity
                android:name=".activity.taskStack.Task2CActivity"
                android:taskAffinity="cn.feng.skin.demo"
                android:exported="true" />
    
            <activity
                android:name=".activity.taskStack.Task2DActivity"
                android:taskAffinity="cn.feng.skin.demo"
                android:exported="true" />

    任务栈打印情况如下:

    * Task{25a9ee #41 type=standard A=10148:com.i.designpattern U=0 visible=true mode=fullscreen translucent=false sz=4}
            bounds=[0,0][720,1280]
            * ActivityRecord{e3c49cf u0 cn.feng.skin.demo/.activity.Task2DActivity t41}
            * ActivityRecord{9bf26f8 u0 cn.feng.skin.demo/.activity.Task2CActivity t41}
            * ActivityRecord{b25ca44 u0 com.i.designpattern/.activity.taskStack.DetailActivity t41}
            * ActivityRecord{5424397 u0 com.i.designpattern/.activity.MainActivity t41}

    结论1:不同应用/进程下,taskAffinity不同,则任务栈相同(都在启动activity的任务栈)。

    2、配置singleTask,且taskAffinity也不同

    //A应用
            <activity
                android:name=".activity.MainActivity"
                android:taskAffinity="com.i.designpattern" />
    
            <activity
                android:name=".activity.taskStack.DetailActivity"
                android:taskAffinity="com.i.designpattern" />
    
    //B应用      
            <activity
                android:name=".activity.Task2CActivity"
                android:taskAffinity="cn.feng.skin.demo"
                android:launchMode="singleTask"
                android:exported="true"/>
    
            <activity
                android:name=".activity.Task2DActivity"
                android:taskAffinity="cn.feng.skin.demo"
                android:launchMode="singleTask"/>

    任务栈打印情况如下:

    * Task{8b1fd9 #53 type=standard A=10147:cn.feng.skin.demo U=0 visible=true mode=fullscreen translucent=false sz=2}
            bounds=[0,0][720,1280]
            * ActivityRecord{82536e0 u0 cn.feng.skin.demo/.activity.Task2DActivity t53}
            * ActivityRecord{af45787 u0 cn.feng.skin.demo/.activity.Task2CActivity t53}
          
    * Task{71b6b2c #52 type=standard A=10148:com.i.designpattern U=0 visible=false mode=fullscreen translucent=true sz=2}
            bounds=[0,0][720,1280]
            * ActivityRecord{bfe4ef2 u0 com.i.designpattern/.activity.taskStack.DetailActivity t52}
            * ActivityRecord{998403d u0 com.i.designpattern/.activity.MainActivity t52}

    结论2:不同应用/进程下,配置singleTask,taskAffinity不同,则任务栈不同、

    3、验证结论2

    //A应用
            <activity
                android:name=".activity.MainActivity"
                android:taskAffinity="com.i.designpattern" />
    
            <activity
                android:name=".activity.taskStack.DetailActivity"
                android:taskAffinity="com.i.designpattern" />
    
    //B应用      
            <activity
                android:name=".activity.Task2CActivity"
                android:taskAffinity="cn.feng.skin.demo"
                android:exported="true"/>
    
            <activity
                android:name=".activity.Task2DActivity"
                android:taskAffinity="cn.feng.skin.demo"
                android:launchMode="singleTask"/>

    任务栈打印情况如下:

    * Task{57ceeb3 #56 type=standard A=10147:cn.feng.skin.demo U=0 visible=true mode=fullscreen translucent=false sz=1}
            bounds=[0,0][720,1280]
            * ActivityRecord{d45533b u0 cn.feng.skin.demo/.activity.Task2DActivity t56}
          
    * Task{550518d #55 type=standard A=10148:com.i.designpattern U=0 visible=false mode=fullscreen translucent=true sz=3}
            bounds=[0,0][720,1280]
            * ActivityRecord{c4f05f u0 cn.feng.skin.demo/.activity.Task2CActivity t55}
            * ActivityRecord{a881b38 u0 com.i.designpattern/.activity.taskStack.DetailActivity t55}
            * ActivityRecord{1769cea u0 com.i.designpattern/.activity.MainActivity t55}

    结论3:不同应用/进程下,taskAffinity不同,则任务栈还相同;配置了singleTask,则任务栈才不同。

    由以上全部内容总结得出以下结论:

    1、同一进程下,只有配置singleTask,且taskAffinity不相同,则开启新的任务栈,其他情况均在同一任务栈下;

    2、不同应用/进程下,只有配置singleTask,且taskAffinity不相同,任务栈才会不同,如果只是taskAffinity不同,则任务栈还会相同;

    由以上1、2得出以下:

    1、同一进程或者不同进程下,前提配置singleTask,如果没有指定taskAffinity,则为当前的任务栈,如果指定了taskAffinity,则查找或创建对应的任务栈,将activity作放置其中;

    2、任何情况下,只有配置singleTask,且taskAffinity不相同,才会开启新的任务栈。

    展开全文
  • } }至于MainActivity和OtherActivity的差别: MainActivity是standard启动模式 OtherActivity是singleTask启动模式 在AndroidManifest.xml中MainActivity默认就是standard启动模式 配置一下OtherActivity就好 ...

    先看一下standard启动模式的说明:

    仅仅有一个实例。在同一个应用程序中启动他的时候。若不存在此Activity实例。则会在当前栈顶创建一个新的实例。若存在,则会把栈中在其上的其他Activity实例销毁掉,并调用此实例的OnNewIntent方法,假设实在别的应用实例中启动它。则会新建一个栈,并在该栈中启动这个Activity,然后我在这个Activity实例中再打开新的Activity这个新的实例会在一个栈中

    我们首先通过一个实例理解这句:仅仅有一个实例。在同一个应用程序中启动他的时候,若不存在此Activity实例。则会在当前栈顶创建一个新的实例。若存在,则会把栈中在其上的其他Activity实例销毁掉,并调用此实例的OnNewIntent方法

    首先在手机上的效果

    4db704ffd651dab8b93b1d757692894d.png

    xml布局文件 两个button 一个用于打开MainActivity(Activity1),一个用于打开OtherActivity(Activity2)

    MainActivity和OtherActivity同一时候使用这个布局文件,并为其button加入点击事件

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MainActivity" >

    android:id="@+id/button1"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_alignParentLeft="true"

    android:layout_centerVertical="true"

    android:layout_marginLeft="46dp"

    android:text="Activity1" />

    android:id="@+id/button2"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_alignBottom="@+id/button1"

    android:layout_marginLeft="48dp"

    android:layout_toRightOf="@+id/button1"

    android:text="Activity2" />

    MainActivity

    package com.example.singletop;

    import android.os.Bundle;

    import android.app.Activity;

    import android.content.Intent;

    import android.view.Menu;

    import android.view.View;

    import android.view.View.OnClickListener;

    import android.widget.Button;

    public class MainActivity extends Activity implements OnClickListener{

    private Button btn_open1,btn_open2;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    //设置标题为Activity1

    setTitle("我是Activity1");

    btn_open1=(Button) findViewById(R.id.button1);

    btn_open2=(Button) findViewById(R.id.button2);

    btn_open1.setOnClickListener(this);

    btn_open2.setOnClickListener(this);

    }

    @Override

    public void onClick(View v) {

    // TODO Auto-generated method stub

    switch(v.getId()){

    case R.id.button1:

    startActivity(new Intent(MainActivity.this,MainActivity.class));

    break;

    case R.id.button2:

    startActivity(new Intent(MainActivity.this,OtherActivity.class));

    break;

    }

    }

    }

    OtherActivity

    package com.example.singletop;

    import android.os.Bundle;

    import android.app.Activity;

    import android.content.Intent;

    import android.util.Log;

    import android.view.Menu;

    import android.view.View;

    import android.view.View.OnClickListener;

    import android.widget.Button;

    public class OtherActivity extends Activity implements OnClickListener{

    private Button btn_open1,btn_open2;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    //设置标题为Activity2

    setTitle("我是Activity2");

    btn_open1=(Button) findViewById(R.id.button1);

    btn_open2=(Button) findViewById(R.id.button2);

    btn_open1.setOnClickListener(this);

    btn_open2.setOnClickListener(this);

    }

    @Override

    public void onClick(View v) {

    // TODO Auto-generated method stub

    switch(v.getId()){

    case R.id.button1:

    startActivity(new Intent(OtherActivity.this,MainActivity.class));

    break;

    case R.id.button2:

    startActivity(new Intent(OtherActivity.this,OtherActivity.class));

    break;

    }

    }

    //在此方法中打印是否调用这种方法的日志

    @Override

    protected void onNewIntent(Intent intent) {

    // TODO Auto-generated method stub

    super.onNewIntent(intent);

    Log.d("OtherActivity", "OnNewIntent");

    }

    }至于MainActivity和OtherActivity的差别:

    MainActivity是standard启动模式

    OtherActivity是singleTask启动模式

    在AndroidManifest.xml中MainActivity默认就是standard启动模式

    配置一下OtherActivity就好

    android:name="com.example.singletop.OtherActivity"

    android:launchMode="singleTask"

    >

    我们举个样例。

    Activity1->Activity2->Activity1->Activity1->Activity2

    在Activity栈中是什么样子呢?

    82e7088a13ede448e2e884622e5b1a38.png

    为什么是这样呢?聪明的你肯定理解了吧?哈哈~

    我们细致分析一下,当我们打开Activity1,栈中仅仅有(Activity1),当再打开Activity2栈里面为(Activity2,Activity1),再打开Activity1栈里面为(Activity1,Activity2,Activity1),再打开Activity1栈里面仍然是正常的(Activity1,Activity1,Activity2,Activity1),以下是重点了。当我们再打开Activity2时发现栈里面已经有了Activity2了,依据singleTask模式的说明(仅仅有一个实例,在同一个应用程序中启动他的时候。若不存在此Activity实例,则会在当前栈顶创建一个新的实例,若存在,则会把栈中在其上的其他Activity实例销毁掉)

    此时会删除栈里面的(Activity1,Activity1)而且调用onNewIntent方法。我们查看一下日志文件

    a329b52fa17efdc8b9ba1f02c45e7b7a.png

    的确调用了一次OnNewIntent方法。仅仅须要按两次返回键就能返回到主界面了。

    聪明的你理解了吧?至于下半句的分析请看下篇文章

    展开全文
  • 另外,我们知道,如果一个Activity设置了"singleTask"启动模式,再次创建这个Activity实例时会先查看任务栈是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部Destroy掉,使...
  • android singleInstance 和 singleTask 的区别

    千次阅读 2022-04-14 14:14:02
    singleInstance 和 singleTask 的区别:singleInstance 保证了在同一时刻,系统只会存在一个这样的 Activity 实例,而 singleTask 模式的 Activity 是可以有多个实例的,只要这些 Activity 在不同的任务栈中即可,...
  • 写了两个Activity 启动模式都设置为singleTask,当我点击应用图标 首先进入Activity1 再点击按钮 进入Activity2 , 此时我按home键返回手机主页面 再点击该应用 但是却回到了Activity1,正常来说...
  • 众所周知,Android中Activity有四种启动方式,他们分别是:standard,singleTop,singleTask,singleInstance,下面对进行一一详解。Standard-默认模式标准启动模式,也是activity的默认启动模式。在这种模式下启动...
  • 我们知道SingleTask模式对于Activity的影响如下:例如我们将Activity A设置为SingleTask模式,其他的Acitivity设置为Standard模式,则有以下效果:A -> B -> C -> D 我们将Activity A一直跳转到Activity D...
  • Android的Activity的Launch模式之SingleTask案例,实际案例源码
  • 三、singleTask简单分析 1、实例 2、验证singleTask的几个特点 3、简单总结singleTask的特点 四、singleInstance的简单分析 1、验证singleInstance的几个特点 2、简单总结singleInstance的...
  • 最后说一下另一种情况,如果你一定想要在启动页设置为SingleTask/SingleInstance(不设置活不下去了),那也有办法,就是添加个闪屏界面(SplashActivity设置为SingleTask/SingleInstance),然后启动MainActivity,...
  • 因项目需要,咱这有个singleTask模式的MainActivity,是个FragmentActivity。进入到别的功能页面后,经常在获得功能结果时,需要使用startActivity调起MainActivity。此时,activity栈中,刚才在MainActivity上面堆...
  • 关于Android activity的启动模式一共有四种 standard singleTop singleTask singleInstance 这四种standard 和singleTop都比较好理解,这里主要研究一下 singleTask singleInstance的区别首先是:singleTask假设...
  • singleTask模式 单任务栈顶复用模式 我的理解是这个任务等一下我还要用,先停止一下,我用的时候在启动 class FirstActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ...
  • 将Activity指定为singleTask的启动模式,效果和在xml中指定启动模式是一样的,同时指定的话,java代码设置高于xml文件配置。 FLAG_ACTIVITY_SINGLE_TOP 将Activity指定为singleTop启动模式,效果和在xml中...
  • 如果您使用singleInstance或singleTask,则需要了解taskAffinity的工作原理,并且还需要确保为每个声明为“singleTask”或“singleInstance”的活动设置不同的应用程序图标(可能还有app标签) .如果不是,由于最近任务...
  • 一、 singleTask ( 栈内复用模式 ) Activity 实例在返回堆栈中的位置、 二、 singleTask ( 栈内复用模式 ) Activity 启动的五种情况、 三、 singleTask 栈内复用模式 任务栈处理 ( 前台任务栈 | 后台任务栈 )、 ...
  • 今天学习到在activity A已经启动的前提下,如果在其他页面操作后再次跳转A,如果A为SingleTask模式,那么A会把在它之上的所有activity销毁从而让它至于栈顶。 那么我有个问题,一个APP点击退出后跳转至登录界面,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,572
精华内容 9,828
关键字:

singletask