16.Android Activity的launchMode

来源:互联网 发布:网络摄像头ip地址查询 编辑:程序博客网 时间:2024/04/30 17:32

16.Android Activity的launchMode

  • Android Activity的launchMode
    • Activity Task
    • standard
      • Android 5点0之前
      • Android 5点0之后
      • 使用场景
    • singleTop
      • 5点0前后和standard一样
      • 使用场景
    • singleTask
      • 一个App中
      • 不同App
      • Google关于singleTask的描述
      • taskAffinity属性
      • 使用场景
    • singleInstance
      • 使用情况
    • Intent Flags


Activity Task

Android系统中Activity的设计是很巧妙的。在内存管理上的设计影响多任务管理在Android系统中运行自如。

Android Task:指的是与用户交互的Activity实例的集合。

Task是以栈的形式存放在,这个栈就是Activity的回退栈。


standard

android:launchMode="standard"

standard是android:launchMode的默认值,无论是android:launchMode=”standard”,还是没有设置android:launchMode属性,Activity都是以standard模式启动的。

细心的同学可以发现,有这样的情景:如果你点击一个控件去执行一次startActivity,如果是一个低性能的Android手机,你在页面没跳转前点了N次,就会发现启动了N个新的Activity,这就是standard模式,这种模式能让你能够创建多个一个新的Activity。

Android 5点0之前

设置了android:launchMode="standard"的Activity,新生成的实例会放入发送Intent的Task的栈顶部。

Created with Raphaël 2.1.0Activity-2Activity-1Task底

跨程序之间调用: 新开启的Activity会放入发送Intent的Task的顶部,虽然他们不是同一个App,但是还不可思议的叠在一起了

Created with Raphaël 2.1.0App2-Activity-2App1-Activity-1Task底

Android 5点0之后

跨应用之间启动Activity,会创建一个新的Task,新生成的Activity就会放入新的Task中。

Created with Raphaël 2.1.0App1_TaskApp1_TaskApp2_TaskApp2_Task

使用场景

使用场景: standard可以用在类似于朋友圈发动态的Activity,发一个动态就创建一个Activity。


singleTop

singleTop和standard基本一样,singleTop拥有standard特性,可以无限创建新的Activity,但是,当且仅当,如果start的Activity已经位于调用Activity所在的Task的栈顶,则不创建新的Activity,而是使用当前的这个Activity实例,并调用这个实例的onNewIntent方法。

注: 如果使用了singleTop,就要处理Activity的onCreate和onNewIntent两个方法,确保逻辑正常。

VActivity.startActivity(new Intent(V.this,VActivity.class)) 前:

Created with Raphaël 2.1.0VActivityAActivityTask底

VActivity.startActivity(new Intent(V.this,VActivity.class)) 后:

Created with Raphaël 2.1.0VActivityAActivityTask底

看似没什么变化,其实走了一遍onNewIntent()方法

5点0前后和standard一样

  • 只有在调用Activity和目标Activity在同一Task中,并且目标Activity位于栈顶,才能使用现有目标Activity实例,否则跟standard一样,不断创建新的目标Activity实例。
  • 如果是外部程序启动singleTop的Activity,在Android 5.0之前新创建的Activity会位于调用Activity的Task中,5.0及以后会放入新的Task中

使用场景

**使用场景:**singleTop一个典型的使用场景是搜索功能。假设有一个搜索框,每次搜索查询都会将到SearchActivity查看结果,为了更好的交互体验,在结果页顶部也放置这样的搜索框。如果SearchActivity的launchMode设置为standard,意味着每次搜索都要创建一个SearchActivity,有个N个SearchActivity,就要按下N次Back键才能返回,这样的设计是不合理的。

使用singleTop的话,当进行了一次搜索后,SearchActivity会在栈顶。即使有新的搜索需求的时候,也不会创建SearchActivity了,而且Back键只需要按一次即可回到进入搜索前的页面。


singleTask

singleTask这个模式和其他启动模式很差异很大。singleTask模式的Activity,系统中只会存在一个。如果这个Activity已经创建过了,则intent就会通过onNewIntent传递到这个Activity;如果这个Activity一开始就没创建,那么会被创建。singleTask模式只会在Activity创建后,到能看到其的特点。

一个App中

  • 如果系统中不存在singleTask Activity,那么就创建这个Activity的实例,并且将这个实例放入和调用Activity相同的Task中并位于栈顶(这里与singleTop和standard类似)。
Created with Raphaël 2.1.0AActivityTask底

AActivity.startActivity(new Intent(AActivity.this,SingleTaskActivity.class))后

Created with Raphaël 2.1.0SingleTaskActivityAActivityTask底
  • singleTask Activity已然存在,那么在Activity Task中,所有位于singleTask Activity上面的所有Activity都将被销毁掉(销毁过程会调用Activity生命周期回调),这样使得singleTask Activity实例位于栈顶。与此同时,Intent会通过onNewIntent传递到这个singleTask Activity。
Created with Raphaël 2.1.0MActivityLActivitySingleTaskActivityVActivityAActivityTask底

MActivity.startActivity(new Intent(MActivity.this,SingleTaskActivity.class))后

Created with Raphaël 2.1.0SingleTaskActivityVActivityAActivityTask底

可以看得出来: MActivity、LActivity、UActivity都被销毁了,并正常执行了它们销毁时的生命周期(如onDestroy)。最后来到SingleTaskActivity.onNewIntent生命周期内。

不同App

  • 不同App的Intent传递时,如果系统中不存在singleTask Activity,那么会创建一个新Task,然后创建SingleTask Activity的,将其放入新的Task中。

  • 如果singleTask Activity所在的App进程存在,但是singleTask Activity不存在,那么从另外一个App启动这个Activity,新的Activity实例会被创建,放入到所属进程所在的Task中,并位于栈顶位置。

  • 如果singleTask Activity存在,从其它App中启动,那么这个singleTask Activity所在的Task会被移到顶部,然后在这个Task中,位于singleTask Activity之上的所有Activity将会被正常销毁。如果按返回键,那么先回退到这个Task中的其它Activity,直到当前Task的Activity回退栈为空时,才会返回到调用App进程中的Task。

Google关于singleTask的描述

The system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time. Although the activity starts in a new task, the BACK key still returns the user to the previous activity.

意思是: 系统会创建一个新的Task,然后singelActivity会放入这个新Task的底部。

写了一个如上图的Demo:

Created with Raphaël 2.1.0SingleTaskActivityVActivityAActivityTask底

运行到SingleTaskActivity的时候,查看Activity任务栈发现,SingleTaskActivity创建的时候,系统没有创建一个新的Task,而是放入了调用Activity的Task中

adb shell dumpsys activity 可以查看Android的Activity任务栈

singletask_1

如图,看到SingleTaskActivity与VActivity、AActivity在同一个栈中。

taskAffinity属性

android:launchMode=singleTask的同时,再设置android:taskAffinity

可以实现启动这个Acitivity时,会创建一个新的Task,再将这个Activity放入新Task中

这里写图片描述

使用场景

使用场景: 其实这样的场景不算多也不算少,如果一个App里有社区,那么每个用户的App看到的社区也是一样的,推送进来也会调用这个社区,这里就可以使用singleTask。


singleInstance

singleInstance比singleTask容易理解一些,它和singleTask一样,只会存在一个个这样的Activity。唯一不同的是,存放singleInstance Activity的Task只能存放一个该模式的Activity实例 。如果从singleInstance Activity启动另一个Activity,那么这个Activity会放入其他的Task中;如果singleInstance Activity被别的Activity启动,它也会放入不同于调用Activity的Task中

使用情况

基本很少使用,Launcher中可能使用。或者需要使Activity是单例。


Intent Flags

启动模式的设置如果不想在manifest中配置,还可以在Intent中设置。

Intent intent = new Intent();intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);                this.startActivity(new Intent(this,SingleTopActivity.class));
0 0
原创粉丝点击