精华内容
下载资源
问答
  • Activity启动模式

    2012-11-15 13:42:10
    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的...Activity启动模式设置: ".MainActivity" android:launchMode="st

     在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。

      Android总Activity的启动模式分为四种:

    复制代码
    Activity启动模式设置:
    
            <activity android:name=".MainActivity" android:launchMode="standard" />
    
    Activity的四种启动模式:
    
        1. standard
    
            模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中。
    
        2. singleTop
    
            如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。
    
        3. singleTask
    
            如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。 
    
        4. singleInstance
    
            在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity的实例存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。
    复制代码

     

      其中standard是系统默认的启动模式。

     

      下面通过实例来演示standard的运行机制:

    复制代码
     1 private TextView text_show;
     2     private Button btn_mode;
     3     
     4     @Override
     5     public void onCreate(Bundle savedInstanceState) {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.activity_main);
     8         
     9         text_show = (TextView) this.findViewById(R.id.text_show);
    10         
    11         text_show.setText(this.toString());
    12         
    13         btn_mode = (Button) this.findViewById(R.id.btn_mode);
    14         
    15     }
    16     
        //按钮单击事件 17 public void LaunchStandard(View v){ 18 startActivity(new Intent(this,MainActivity.class)); 19 20 text_show.setText(this.toString()); 21 }
    复制代码

      初始化界面如下:

      

      当点击按钮时,会创建新的Activity,通过TextView@后16进制数的显示即可看出,点击两次分别界面如下:

      

       

      

      此时,我们分析栈内部的运行机制:

       (依次从栈顶向上)

     

      因此,这种Standard模式是每次都会创建新的Activity对象,当点击返回按钮时,他会将栈顶(当前Activity)消灭,然后跳到下一层,例如如果现在Activity是44ed8c50,那么当我们点击返回时Activity会变为44f28a48,不过此时在这个Activity中再次点击按钮创建对象时,它会另外创建新的Activity对象,这种模式可能大多数情况下不是我们需要的,因为对系统性能的消耗过大。

      下面我们介绍两种能使用当前栈中Activity的启动模式:

      2. singleTop

        从上面的解释中即可知道,在每次使用新的Activity时会自动检测栈顶的当前Activity是否是需要引用的Activity,如果是则直接引用此Activity,而不会创建新的Activity。

        我们在刚才的界面中加入一个"启动singletop模式"按钮,当点击时出现我们创建的singletop中,在Activity singletop中有一个按钮,启动singletop模式,表示启动当前Activity,由于我们在清单文件中配置Activity的启动模式为singleTop,因此此时不会再创建而是利用当前栈顶的singleTop Activity:

         <activity
                android:name=".SingleTopActivity"
                android:label="@string/singletop"
                android:launchMode="singleTop" >
            </activity>

     

     

        界面初始化:

          

        点击"启动singleTop模式"按钮:

              

      我们分析它的运行机制,可知,当程序运行到此时,栈中的数据形式为:

        

        当我们在上面界面中点击"启动singleTop模式"按钮时,由于此Activity设置的启动模式为singleTop,因此它首先会检测当前栈顶是否为我们要请求的Activity对象,经验证成立,因此它不会创建新的Activity,而是引用当前栈顶的Activity。

           

        虽然它不会创建新的Activity对象,不过它每次会调用onNewIntent()方法

    复制代码
    1 @Override
    2     protected void onNewIntent(Intent intent) {
    3         // TODO Auto-generated method stub
    4         super.onNewIntent(intent);
    5         
    6         Toast.makeText(this, new Date().toString(), 1).show();
    7     }
    复制代码

     

        我们为此方法编写代码输出当前日期,则在每次点击上面按钮时会输出当前日期。

     

      3.singleTask

        此启动模式和singleTop在名字上即可看出区别,即singleTop每次只检测当前栈顶的Activity是否是我们需要请求创建的,而singleTask则会检测栈中全部的Activity对象,从上向下,如果检测到是我们所请求的则会消灭此Activity对象上面的对象,直接把检测到的我们需要的Activity置为栈顶。

        我们创建一个SingleTaskActivity,此界面中包含一个启动MainActivity和启动SingleTaskActivity按钮。

      初始化:

        

      点击"启动singleTask模式"按钮:

        

      在此界面中点击第二个按钮"启动singleTask模式"按钮,根据定义会检测当前栈中是否有此Activity对象,因此显示的还是当前的Activity,不会重新创建;

      再点击"启动Standard模式"按钮,由于MainActivity的启动模式为standard,所以在此会重新创建一个MainActivity对象:

        

      此时栈中数据格式为:

        

      当在上面界面中点击"启动singleTask模式"按钮时,由于检测到当期栈中第二个为我们要创建的Activity,会将最上面的MainActivity消灭,然后将SingleTaskActivity设置为栈顶:

        

     

      4.SingleInstance

        此启动模式和我们使用的浏览器工作原理类似,我们都知道在多个程序中访问浏览器时,如果当前浏览器没有打开,则打开浏览器,否则会在当前打开的浏览器中访问。此模式会节省大量的系统资源,因为他能保证要请求的Activity对象在当前的栈中只存在一个。

     

        

        上面即为Android中的四种启动模式,我们在开发Android项目时会经常使用到,巧妙设置Activity的启动模式会节省系统开销和程序运行效率。

    展开全文
  • Activity启动模式

    2019-10-23 07:48:55
    上篇文章Activity启动模式一主要介绍了Activity的四种启动模式,这些启动模式都是在AndroidManifest中进行配置的。除此之外,Android系统还通过Intent类提供了一些标志位,同样可以指定Activity的启动模式。本文将...

    上篇文章Activity启动模式一主要介绍了Activity的四种启动模式,这些启动模式都是在AndroidManifest中进行配置的。除此之外,Android系统还通过Intent类提供了一些标志位,同样可以指定Activity的启动模式。本文将介绍下这些和Activity启动相关的标志位。

    一般情况下,我们在启动目标Activity的Intent中指定这些标志位,如下所示:

    Intent intent = new Intent();
    intent.setClass(MainActivity.this,FirstActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    startActivity(intent);

    当同时在配置文件中指定launchMode和在Intent中指定上面的标志位时,以标志位为准,即代码的优先级比AndroidManifest的优先级更高!

    下面我们通过具体案例看下和Activity启动相关的4种标志位:

    Activity启动相关的四种标志位

    FLAGACTIVITYNEW_TASK

    官方文档上介绍该标志位和SingleTask启动模式具有相同效果,其实不然。应该是FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP一起等同于SingleTask启动模式。

    这里我们通过4个案例,看下单独使用FLAGACTIVITYNEWTASK标志位和一起使用FLAGACTIVITYNEWTASK、FLAGACTIVITYCLEAR_TOP标志位的具体效果。

    案例1

    两个Activity的taskAffinity属性相同,具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,且两者的启动模式都是Standard,TaskAffinity也相同。
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAGACTIVITYNEW_TASK标志位,启动MainActivity的Intent不包含任何标志位。

    经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:new_task-taskAffinity相同-1可见,因为两个Activity的taskAffinity属性相同,所以第一次启动FirstActivity时并没有创建新的任务栈。

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:new_task-taskAffinity相同-2因为只有FLAGACTIVITYNEWTASK标志位,没有FLAGACTIVITYCLEARTOP,所以无法清除FirstActivity之上的MainActivity,复用已有FirstActivity。而是创建了新的FirstActivity。

    通过上面的任务栈可知:在taskAffinity相同的情况下,单独添加FLAGACTIVITYNEW_TASK不起任何作用。

    案例2

    两个Activity的taskAffinity属性不相同,具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,且两者的启动模式都是Standard,但是TaskAffinity不同。
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAGACTIVITYNEW_TASK标志位,启动MainActivity的Intent不包含任何标志位。

    经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:new_task-taskAffinity不同-1可见,因为两个Activity的taskAffinity属性不同,所以第一次启动FirstActivity时,创建了新的任务栈(TaskId为1979).

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:new_task-taskAffinity不同-2可以看到,任务栈没有发生任何变化,也没有创建新的FirstActivity实例。这是因为FirstActivity实例已经存在于它所期望的任务栈中,而单独添加FLAGACTIVITYNEW_TASK标志位又不会清除任务栈中位于FirstActivity之上的Activity实例,所以就没有发生跳转。

    通过上面的任务栈可知:在taskAffinity不同的情况下,第一次启动FirstActivity时,会新建一个任务栈,并将FirstActivity实例添加到该task中。这与SingleTask启动模式产生的效果是一致的。但是,当企图再次从MainActivity进入到FirstActivity时,却什么也没有发生,原因上面已经说明了。

    综上所述,单独使用FLAGACTIVITYNEWTASK会产生非常奇怪的行为,因此一般和FLAGACTIVITYCLEARTOP标志位一起使用,这样可以实现类似SingleTask的效果,但是不完全相同,下面会进行介绍。

    下面我们再通过两个案例看下FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP一起使用的效果。

    案例3

    两个Activity的taskAffinity属性相同,具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,且两者的启动模式都是Standard,TaskAffinity也相同。
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP标志位,启动MainActivity的Intent不包含任何标志位.

    经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:new_task-clear_top-taskAffinity相同-1可见,因为两个Activity的taskAffinity属性相同,所以第一次启动FirstActivity时并没有创建新的任务栈。

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:new_task-clear_top-taskAffinity相同-2貌似是和SingTask启动模式的效果相同,但是细看一下就会发现区别:前后两次FirstActivity实例是不同的,也就是没有复用第一次启动的FirstActivity,而是清除了FirstActivity及其之上的所有Activity,然后新建FirstActivity实例添加到了当前任务栈

    通过上面的任务栈可知:在taskAffinity相同的情况下,FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP标志位组合确实不会创建新的任务栈,但是会清除了FirstActivity及其之上的所有Activity,并新建FirstActivity实例添加到了当前任务栈,这点是和SingleTask模式的差异。(SingleTask仅会清除FirstActivity之上的Activity,然后复用已有的FirstActivity)

    案例4

    两个Activity的taskAffinity属性不相同,具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,且两者的启动模式都是Standard,但是TaskAffinity不同。
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP标志位,启动MainActivity的Intent不包含任何标志位。

    经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:new_task-clear_top-taskAffinity不同-1可见,因为两个Activity的taskAffinity属性不同,所以第一次启动FirstActivity时,创建了新的任务栈(TaskId为1980).

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:new_task-clear_top-taskAffinity不同-2可以看到,和案例3 taskAffinity属性相同的情况类似(除了创建了新的任务栈),直接清除了FirstActivity及其之上的所有Activity,然后创建新的FirstActivity实例添加到新的任务栈(TaskId为1980)。

    通过上面的任务栈可知:在taskAffinity不同的情况下,FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP标志位组合会为首次启动的FirstActivity创建新的任务栈,其他的逻辑与案例3基本相同,都是直接清除了FirstActivity及其之上的所有Activity,然后创建新的FirstActivity实例,这也是和SingleTask模式的区别

    综上所述,FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP标志位组合产生的效果总体上和SingleTask模式相同,除了不会复用FirstActivity实例之外。

    FLAGACTIVITYCLEAR_TOP

    该标志位在上面已经使用过了,作用是清除包含目标Activity的任务栈中位于该Activity实例之上的其他Activity实例。但是是复用已有的目标Activity,还是像上面那样先删除后重建,则有以下规则:

    1. 若是单独使用FLAGACTIVITYCLEAR_TOP,那么只有非Standard启动模式的目标Activity才会被复用,其他启动模式的目标Activity都先被删除,然后被重新创建并入栈。
    2. 若是使用FLAGACTIVITYSINGLETOP和FLAGACTIVITYCLEARTOP标志位组合,那么不管目标Activity是什么启动模式,都会被复用。

    因为上面的案例3和案例4都不符合上面的两条规则,所以FirstActivity才会先被清除,然后重建。

    下面我们通过几个具体案例,验证下上面的两条规则:

    案例1

    具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,且两者的启动模式都是Standard。
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAG_ACTIVITY_CLEAR_TOP标志位,启动MainActivity的Intent不包含任何标志位。

    经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:clear_top-standard-1

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:clear_top-standard-2

    通过上面的任务栈可知:第二次MainActivity -> FirstActivity时,会先把FirstActivity以及之上的Activity全部销毁,然后创建新的FirstActivity入栈,正符合我们的预期。

    案例2

    具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,MainActivity的启动模式是Standard,FirstActivity的启动模式是SingleTop。
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAG_ACTIVITY_CLEAR_TOP标志位,启动MainActivity的Intent不包含任何标志位。

    经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:clear_top-SingleTop-1

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:clear_top-SingleTop-2

    通过上面的任务栈可知:第二次MainActivity -> FirstActivity时,会先把FirstActivity之上的Activity全部销毁,然后复用已有的FirstActivity实例,也符合我们的预期。

    此外,当FirstActivity是SingleTask和SingleInstance模式时,其效果和SingleTop启动模式一样,也是首先销毁FirstActivity之上的所有Activity,然后复用已有的FirstActivity实例。

    这里仅给出我验证的任务栈:当FirstActivity是SingleTask模式时(taskAffinity相同),经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:clear_top-SingleTask-1

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:clear_top-SingleTask-2可见,确实复用了已有的FirstActivity实例。

    当FirstActivity是SingleInstance模式时,经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:clear_top-SingleInstance-1

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:clear_top-SingleInstance-2可见,确实复用了已有的FirstActivity实例。

    综上所述,通过案例1和案例2,我们验证了规则1是OK的。下面我们继续验证下规则2:

    案例3

    具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,且两者的启动模式都是Standard。
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_CLEAR_TOP标志位,启动MainActivity的Intent不包含任何标志位。

    经过MainActivity -> FirstActivity -> MainActivity后,最终的任务栈如下所示:single_top-clear_top-1

    最后,MainActivity再次启动FirstActivity后,最终的任务栈如下所示:single_top-clear_top-2

    通过上面的任务栈可知:第二次MainActivity -> FirstActivity时,会先把FirstActivity之上的Activity全部销毁,然后复用已有的FirstActivity实例,也符合我们的预期。

    综上所述,既然在FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_CLEAR_TOP标志位组合的情况下,Standard模式的FirstActivity都已经被复用了,那么其他启动模式的Activity也必然会被复用。(单独使用FLAGACTIVITYCLEARTOP都会被复用,何况又添加了FLAGACTIVITYSINGLETOP标志位,通过Demo验证也确实如此,就不再给出具体案例了)。

    综上所述,上面的两条规则还要是遵守的^_^。

    FLAGACTIVITYCLEAR_TASK

    该标志位一般和FLAGACTIVITYCLEAR_TASK一起使用,目的是启动目标Activity时,首先清空已经存在的目标Activity实例所在的任务栈,这自然也就清除了之前存在的目标Activity实例,然后创建新的目标Activity实例并入栈。

    经过Demo测试发现,单独使用FLAGACTIVITYCLEAR_TASK标志位,不管taskAffinity是否相同,都不会产生什么效果。例如下面是单独使用该标志位的最终任务栈(taskAffinity相同 or 不同都是这样):clear_task感兴趣的可以自行尝试,这里不再赘述。

    下面看下FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TASK标志位组合在taskAffinity相同 and 不同的情况下的效果。

    案例1

    两个Activity的taskAffinity属性相同,具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,且两者的启动模式都是Standard,taskAffinity也相同
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TASK标志位,启动MainActivity的Intent不包含任何标志位。

    第一次启动MainActivity后,任务栈如下所示:new_task-clear_task-1

    接着MainActivity启动FirstActivity后,任务栈如下所示:new_task-clear_task-2首先启动的MainActivity居然被清除了,然后才创建了FirstActivity实例。

    然后FirstActivity启动MainActivity后,任务栈如下所示:new_task-clear_task-3

    最后MainActivity再次启动FirstActivity后,任务栈如下所示:new_task-clear_task-4可见,系统再次清除了FirstActivity及其之上的MainActivity,然后重新创建了新的FirstActivity实例并入栈。

    通过上面的任务栈可知:当通过FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TASK标志位组合启动FirstActivity时,首先会清空FirstActivity所在的任务栈,然后再创建新的FirstActivity实例并入栈

    案例2

    两个Activity的taskAffinity属性不相同,具体步骤如下所示:

    1. 创建MainActivity和FirstActivity,且两者的启动模式都是Standard,taskAffinity不相同
    2. 首先启动MainActivity,接着通过MainActivity启动FirstActivity,然后再通过FirstActivity启动MainActivity,如此反复。
    3. 启动FirstActivity的Intent中指定了FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TASK标志位,启动MainActivity的Intent不包含任何标志位。

    第一次MainActivity启动FirstActivity后,任务栈如下所示:new_task-clear_task-5因为taskAffinity不同,所以为FirstActivity实例创建了新的任务栈。

    然后FirstActivity启动MainActivity后,任务栈如下所示:new_task-clear_task-6

    最后MainActivity再次启动FirstActivity后,任务栈如下所示:new_task-clear_task-7可见,系统首先清除了任务栈(TaskId为2040)中FirstActivity及其之上的MainActivity,然后重新创建了新的FirstActivity实例并入栈(TaskId为2040)。

    通过上面的任务栈可知:当通过FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TASK标志位组合启动FirstActivity时,首先会清空FirstActivity所在的任务栈,然后再创建新的FirstActivity实例并入栈,这和taskAffinity属性相同是一致的效果,只不过这里第一次为FirstActivity创建了新的任务栈

    综上所述,当通过FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TASK标志位组合启动目标Activity时,首先会清空目标Activity所在的任务栈(若目标Activity是第一次启动,那么会清空目标Activity所期望的任务栈),然后创建新的目标Activity实例并入栈。

    FLAGACTIVITYSINGLE_TOP

    该标志单独使用就可以达到SingleTop启动模式的效果,该类效果可以参考前篇文章,这里不再赘述。

    Activity启动相关的属性

    这里简单介绍一些AndroidManifest配置文件中与启动模式相关的属性。其实前一篇文章已经介绍了两个比较常用的属性:android:taskAffinityandroid:allowTaskReparenting,下面再补充一些不常用的属性。

    android:clearTaskOnLaunch

    字面意思是:是否在启动时清除任务栈,该属性默认为false,表示是否在APP启动时,清除任务栈中除根Activity之外的其他Activity实例。该属性只对任务栈内的根Activity起作用,任务栈内其他的Activity都会被忽略。

    比如:我们有一个App,依次启动了ActivityA、ActivityB和ActivityC,其中ActivityA和ActivityB都设置clearTaskOnLaunch属性为true。那么首先点击“Home”建回到Launcher界面,然后再启动该App,我们看到是ActivityA界面,而ActivityB和ActivityC都被销毁了。除非栈底的ActivityA已经被销毁,那么上面设置clearTaskOnLaunch属性为true的activity(B)才会生效。

    android:finishOnTaskLaunch

    该属性默认值为false,表示当离开当前Activity所在的任务栈时,立即销毁当前Activity,而其他Activity不受影响。

    android:alwaysRetainTaskState

    该属性默认值为false,表示App的任务栈是否保持原来的状态。该属性只对task的根Activity起作用,其他的Activity都会被忽略。 默认情况下,若一个App在后台停留的时间太长,那么再启动该App时,系统会清除任务栈中除了根Activity之外的其他Activity,但是如果根Activity设置了该属性,那么再次启动应用时,就不会清除Task中的Activity,而是保持原样,因此仍然可以看到上一次操作的界面。

    OK,Activity启动模式相关的内容就介绍这些吧,希望对自己对感兴趣的同学都有所帮助^_^。

    本文由博客一文多发平台 OpenWrite 发布!

    展开全文
  • 深入Activity,Activity启动模式LaunchMode完全解析 在平时的开发中,我们可能会了解到Activity的任务栈还有Activity的启动模式。那么Activity的启动模式都分别是怎么样的呢?如果设置了这些启动模式对任务栈有事么...

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53221384
    本文出自【DylanAndroid的博客】


    深入Activity,Activity启动模式LaunchMode完全解析

    在平时的开发中,我们可能会了解到Activity的任务栈还有Activity的启动模式。那么Activity的启动模式都分别是怎么样的呢?如果设置了这些启动模式对任务栈有事么影响
    ,还有就是这么启动模式在实际的开发中有什么应用呢?这里用图例和demo来分析一下Activity的启动模式。

    Demo图
    device.png?raw=true

    1.Standard:标准启动模式

    Activity的默认模式,所有的Activity元素遵循先进后出的进栈出栈的特性,这种的比较简单

    启动顺序:A->B->C

    回退顺序:C->B->A.

    Standard

    2.SingleTop:栈顶复用模式

    栈顶复用模式,如果想要打开的activity在任务栈的栈顶已经存在,就不会创重新建新的实例,而是调用该Activity的 onNewIntent() 方法。避免栈顶的activity被重复的创建。

    例如A.B启动模式为Standard,C启动模式为SingleTop

    启动顺序:A->B->C—>C

    回退顺序:C->B->A.而不是C->C->B->A

    SingleTop
    应用如下:
    * 点击通知栏重复打开Activity的问题
    全新的Android通知栏,已抛弃setLatestEventInfo,兼容高版本 这篇文章里面
    我们打开一个通知栏,点击通知栏默认打开MainActivity,有一个问题,就是如果不设置MainActivity的launchMode,就会每次点击通知栏的时候会重新打开一个Activity。
    我们可以将MainActivity的启动模式设置为SingleInstance,就不会再重新打开MainActivity,而是调用MainActivity的onNewIntent() 方法。
    * 可以解决按钮重复点击的问题(当然这种启动模式不是为了去解决这个问题在这里这是说为了用这么应用去说明SingleTop启动模式)。

    3.SingleTask:栈内复用模式

    如果想要启动的Activity在当前栈内启动之后,该activity只会在任务栈里面存在一个实例。如果要再次打开这个activity,在任务栈里面如果已经存在,就不会创建新的activity,
    而是复用栈内的这个已经存在的activity,调用改Activity的 onNewIntent() 方法,并且清空这个activity任务栈上面所有的activity。

    例如A.C.D启动模式为Standard,B启动模式为SingleTask

    启动顺序:A->B->C—>D—>B

    回退顺序:B->A.而不是B—>D->C->B->A

    SingleTop
    应用如下:如果从主页去登录,然后去注册,注册完成如果直接回去主页,可以将主页的launchMode设置为SingleTask。直接从注册跳到主页即可,不用去关心LoginActivity是否关闭,还是什么时候关闭。

    4.SingleInstance:单一实例模式

    在整个Android系统中(可能会有很多任务栈)里面只有一个实例存在。不同的应用程序app去启动这个activity,就会共享公用同一个activity。
    他会运行在自己单独的的任务栈里面,并且这个单独的任务栈里面只会存在着一个实例。而且这个单独的任务栈会在最底层。
    应用场景:系统的发短信,打电话,来电,浏览器等。这种模式在平时很少去使用,一般在Launcher中可能会用到。

    例如A.C启动模式为Standard,B启动模式为SingleInstance

    启动顺序:A->B->C;注意:此时产生了两个任务栈,B产生了一个新的任务栈,并处于其他任务栈的下面。

    回退顺序:C->A->B.而不是C->B->A

    SingleTop

    5.GitHub

    展开全文
  • 1. Activity启动模式singleTask的理解 2. Task与Activity栈 3. singleTask设置方式 4. singleTask的意义(作用) 4.1. 举例说明 4.2. 例子1 4.3. 例子2 4.4. 小结 5. taskAffinity属性 5.1. 配置方式 5.2. 意义...
    
    
    
    

    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、onStart、onResume这些生命周期方法,而是调用了onNewIntent方法。

    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

    展开全文
  • Activity启动模式详解

    千次阅读 2016-08-09 19:15:52
    Activity启动模式详解对应的试验在这 http://blog.csdn.net/Ash_Zheng/article/details/52165402Activity的启动模式实际上是定义了Activity实例与当前Task的关联方式。所以想要清楚的了解Activity的启动模式,首先得...
  • 不太清楚启动模式的建议先看一看启动模式 图文讲解的这个比较详细Activity启动模式图文讲解 Activity启动模式 及 Intent Flags 与 栈 的关联分析在android里,有4种activity的启动模式,分别为: “standard” ...
  • Android基础中的Activity启动模式非常重要 本文将介绍对Activity启动模式进行全面介绍 目录1. 定义即Activity启动的方式2. 启动模式的类别Android启动提供了四种启动方式: 标准模式(standard) 栈顶复用模式...
  • android activity 启动模式有四种。每次启动的activity实例都会保存到任务栈中。 1、standard 标准模式 ,如果不设置,将是每个activity的默认模式。  1)设置为standard模式的activity,每次使用startActivity...
  • android activity启动模式

    2014-11-10 18:45:28
    android activity启动模式
  • Android中Activity启动模式详解  在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。  Android...
  • 1 standard 标准模式,每次都生成一个新的activity,标准启动模式,也是默认启动模式,如果不设置android:launchMode属性的话。...单顶模式,这种Activity启动模式,启动一个Activity的时候如果发现BackStack的
  • Android Activity启动模式分析 standard 标准启动模式 singleTop 栈顶复用模式 singleTask 栈内复用模式 singleInstance 全局单例模式 standard 标准启动模式 该模式也是Android中activity默认的启动模式,每次启动...
  • 在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的...Activity启动模式设置: ".MainActivity" android:launchMode="stan
  • Activity启动模式

    2019-10-23 07:47:40
    众所周知,Activity有4种启动模式,分别是:Standard、SingleTop、SingleTask和SingleInstance,它们控制了被启动Activity的启动行为。本文将通过具体案例,详细分析这几种模式的差异和使用场景,方便日后查阅。 在...
  • Activity启动模式的深入分析

    千次阅读 2015-03-19 00:19:12
    网上关于Activity启动模式的文章非常多,但是看起来都千篇一律,看完之后我们都能理解这4种启动模式,不过官方api对singleTask这个启动模式解释有些争议,导致我其实并没有真正理解这几种模式,特别是对实际开发到底...
  • Activity有很多Flag ,一些Flag可以用来设置启动模式,一些可以用来影响Activity的运行状态,这里介绍常见的FLAG 一般通过在Intent设置: ...一、更改Activity启动模式 FLAG_ACTIVITY_NEW_TASK ...
  • Activity启动模式之singleTask单栈模式

    千次阅读 2016-06-02 15:23:58
    Activity启动模式之singleTask单栈模式单栈模式,意思说白了,就是栈中只能存在同一个Activity,不能有多个相同的Activity,即单栈模式下,栈中不可能会出现两个相同的Activity。 举个例子: 甲Activity设置了...
  • 深入理解Activity启动模式

    千次阅读 2016-04-14 10:14:33
    概述 Android官网介绍Activity的启动模式时比较...大家看了Android官网对Activity启动模式的介绍后,可能会觉得很困惑。官网介绍singleTask启动模式时,说只要启动singleTask启动模式的Activity就会新建Task,但在实
  • -Activity启动模式 Activity有4种启动模式,它们分别是:standard模式(默认),singleTop模式,singleTask模式,singleInstance模式当应用运行起来后就会开启一条线程,线程中会运行一个任务栈,当Activity实例...
  • Android Activity启动模式设置为SingleTask需要注意的地方 当Activity跳转到启动模式为SingleTask的Activity的时候,onRestart()不再回调,而是回调 onNewInstance(Intent intent) 方法,其中参数可以从intent中...
  • Android基础中的Activity启动模式非常重要 本文将介绍对Activity启动模式进行全面介绍 目录 目录 1. 定义 即Activity启动的方式 2. 启动模式的类别 Android启动提供了四种启动方式: 标准模式(standard) ...
  • activity启动模式笔记

    千次阅读 2015-03-01 21:40:17
    activity启动模式的逻辑主要在startActivityUncheckedLocked()函数中,现在来看下这个函数。 final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession...
  • Activity启动模式  可以根据实际的需求为Activity设置对应的启动模式,从而 可以避免大量重复的activity等问题 Activity有四种加载模式 1. standard 2. singleTop 3. singleTask ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 91,543
精华内容 36,617
关键字:

activity启动模式