杭州Android培训
达内杭州Android培训中心

13732203138

热门课程

Activity的4种启动模式

  • 时间:2018-04-12
  • 发布:杭州android中心
  • 来源:企业笔试题

1、standard

这是系统的默认启动模式,每一次新的跳转就会产生新的实例压入栈中。假设有一个activity,名为AActivity,执行startActivity(new Intent(AActivity.this,AActivity.class)后,从当前AActivity跳转到另一个AActivity,栈里就会有2个 AActivity实例。按返回键后会发现“似乎”一直在第一个 AActivity里面。

通过查看手机的activity栈信息来证实这一点,把app运行在手机上,用数据线连接手机和电脑,打开命令终端,输入adb命令:adb -d shell dumpsys activity:

Running activities (most recent first):

TaskRecord{3f57acdf #583 A=com.wong.testlifecycle U=0 sz=3}

Run #6: ActivityRecord{9a4901b u0 com.wong.testlifecycle/.AActivity t583}

Run #5: ActivityRecord{3125795d u0 com.wong.testlifecycle/.AActivity t583}

在终端上再输入adb命令:adb -d shell dumpsys activity -a AActivity -p com.wong.testlifecycle得到指定包名下指定的activity的信息,截取信息如下:

TASK com.wong.testlifecycle id=583

ACTIVITY com.wong.testlifecycle/.AActivity 9a4901b pid=27283

ACTIVITY com.wong.testlifecycle/.AActivity 3125795d pid=27283

可以得出结论:standard启动模式会在一个任务栈(上面显示的两个实例的Task id都是同一个)里不断产生新实例。

2、singleTop

对于singleTop启动模式的Activity,如果在历史栈中已有此activity的实例且在栈顶,那么activity就不会被启动,而直接复用栈顶的那个activity实例,并调用这个实例的onNewIntent方法,intent就会通过onNewIntent传递到这个Activity;否则新建一个实例。

例子:设 AActivity 为 singleTop 启动模式,执行startActivity(new Intent(AActivity.this,AActivity.class)跳转后栈里面依旧只有一个实例,如果现在按返回键程序将直接退出。也就是说AActivity 已经被启动,并且处于历史栈的栈顶,就不会创建新的AActivity实例,而是复用这个已经开启的Activity。

查看手机activity堆栈信息:adb -d shell dumpsys activity

Running activities (most recent first):

TaskRecord{2371f8cf #584 A=com.wong.testlifecycle U=0 sz=1}

Run #4: ActivityRecord{2aa37034 u0 com.wong.testlifecycle/.AActivity t584}

但如果AActivity不是在栈顶,那么就会创建新实例:假设跳转顺序为AActivity->BActivity->CActivity->AActivity,此时AActivity实例就不是在栈顶了,就会创建新实例。再看手机的activity栈信息:adb -d shell dumpsys activity

Running activities (most recent first):

TaskRecord{b6a3acc #585 A=com.wong.testlifecycle U=0 sz=4}

Run #7: ActivityRecord{137609dc u0 com.wong.testlifecycle/.AActivity t585}

Run #6: ActivityRecord{2eb74062 u0 com.wong.testlifecycle/.CActivity t585}

Run #5: ActivityRecord{b69ddac u0 com.wong.testlifecycle/.BActivity t585}

Run #4: ActivityRecord{35b621a2 u0 com.wong.testlifecycle/.AActivity t585}

再查看手机activity的堆栈信息: adb -d shell dumpsys activity -p com.wong.testlifecycle,发现它们是同一个任务栈里的。

Stack #1:

Task id #589

TaskRecord{3a2a4ae8 #589 A=com.wong.testlifecycle U=0 sz=4}

Hist #3: ActivityRecord{213a49b3 u0 com.wong.testlifecycle/.AActivity t589}

Hist #2: ActivityRecord{27cfaab1 u0 com.wong.testlifecycle/.CActivity t589}

Hist #1: ActivityRecord{2de96172 u0 com.wong.testlifecycle/.BActivity t589}

Hist #0: ActivityRecord{363e9d5e u0 com.wong.testlifecycle/.AActivity t589}

由查看手机activity栈信息来看,确实,在singleTop下,不是栈顶就会创建新实例

3、singleTask

对于“singleTask”启动模式的acitvity,如果这个实例已经存在 ,intent就会通过onNewIntent传递到这个Activity,并且将栈中该activity之上的activity清除(销毁过程会调用Activity生命周期回调);否则Activity实例将被创建。

这个对业务流程环节多的app很有帮助。比如:在手机上办理信用卡时,要填写很多信息,过程当中会链式打开很多个activity页面,在提交后,就跳到首页上去,按返回键时也不会出现以前填写信息的页面这种奇怪现象,怎么做到的呢?用singleTask就可以完美解决这个问题了。

假设有这样一个跳转:假设跳转顺序为AActivity->BActivity->CActivity->AActivity。要求是从最后一个页面返回到第一个页面且按返回键时,不会出现中间过程的页面。我们设置AActivity的启动模式设为singleTask 。

查看手机activity的堆栈信息:wong@wong-computer:~$ adb -d shell dumpsys activity,发现 BActivity,CActivity 都被弹出栈了,只剩下第一个页面,符合要求:

Running activities (most recent first):

TaskRecord{35f4cc20 #607 A=com.wong.testlifecycle U=0 sz=1}

Run #3: ActivityRecord{11bcd79d u0 com.wong.testlifecycle/.AActivity t60

4、singleInstance

对于singleInstance 启动模式的Activity,是其所在的栈的唯一activity,它会每次都被重用,而且系统是不会在启动模式singleInstance 的activity的task栈中启动任何其他的activity,任何从这个activity启动的activity都会在其他的栈中被打开。

假设有这样一个跳转:AActivity->BActivity->CActivity->AActivity。AActivity的启动模式设为singleInstance 。

查看手机activity的堆栈的信息: adb -d shell dumpsys activity -p com.wong.testlifecycle,发现singleInstance 启动模式的Activity是独占一个任务栈里的,任何从这个AActivity 启动的activity都会在其他的栈中被打开,而且 AActivity是可重用的,证据就是从CActivity跳转回 AActivity时,没有创建新实例,依旧用回原来那个。

Stack #1:

Task id #605

Hist #0: ActivityRecord{26b92869 u0 com.wong.testlifecycle/.AActivity t605}

Task id #606

Hist #1: ActivityRecord{1f049130 u0 com.wong.testlifecycle/.CActivity t606}

Hist #0: ActivityRecord{ca4e79c u0 com.wong.testlifecycle/.BActivity t606}

5、总结一下:

singleTop和standard几乎一样,使用singleTop的Activity也可以创建很多个实例。唯一不同的就是,如果调用的目标Activity已经位于调用者的Task的栈顶,则不创建新实例,而是使用当前的这个Activity实例,并调用这个实例的onNewIntent方法,Intent就会被传到这个地方来。

singleTop的使用场景比较少,例子比如用户已经在当前activity,用户点击一条推送消息之后也需要跳转到当前activity,那么为了避免activity的重复打开,则需要将该activity设置为singleTop并且复写onNewIntent即可。

如果是外部程序启动singleTop的Activity,表现都和standard一样。

singleInstance和singleTask类似,在系统中都只会存在一个实例,唯一的区别就是系统不会在singleInstance activity的task栈中启动任何其他的activity,singleInstance activity栈中仅仅只能有该activity的实例,其他任何从这个activity启动的activity都会在其他的栈中被打开。

最后,说一说如何设置activity的启动模式的方法,在Manifest.xml中的activity上用android:launchMode=””配置,launchMode的取值:standard、singleTop、singleInstance、singleTask:

<activity

android:name=".BActivity"

android:launchMode="singleInstance"/>

Android开发不得不知的Activity

的4种启动模式

1、standard

这是系统的默认启动模式,每一次新的跳转就会产生新的实例压入栈中。假设有一个activity,名为AActivity,执行startActivity(new Intent(AActivity.this,AActivity.class)后,从当前AActivity跳转到另一个AActivity,栈里就会有2个 AActivity实例。按返回键后会发现“似乎”一直在第一个 AActivity里面。

通过查看手机的activity栈信息来证实这一点,把app运行在手机上,用数据线连接手机和电脑,打开命令终端,输入adb命令:adb -d shell dumpsys activity:

Running activities (most recent first):

TaskRecord{3f57acdf #583 A=com.wong.testlifecycle U=0 sz=3}

Run #6: ActivityRecord{9a4901b u0 com.wong.testlifecycle/.AActivity t583}

Run #5: ActivityRecord{3125795d u0 com.wong.testlifecycle/.AActivity t583}

在终端上再输入adb命令:adb -d shell dumpsys activity -a AActivity -p com.wong.testlifecycle得到指定包名下指定的activity的信息,截取信息如下:

TASK com.wong.testlifecycle id=583

ACTIVITY com.wong.testlifecycle/.AActivity 9a4901b pid=27283

ACTIVITY com.wong.testlifecycle/.AActivity 3125795d pid=27283

可以得出结论:standard启动模式会在一个任务栈(上面显示的两个实例的Task id都是同一个)里不断产生新实例。

2、singleTop

对于singleTop启动模式的Activity,如果在历史栈中已有此activity的实例且在栈顶,那么activity就不会被启动,而直接复用栈顶的那个activity实例,并调用这个实例的onNewIntent方法,intent就会通过onNewIntent传递到这个Activity;否则新建一个实例。

例子:设 AActivity 为 singleTop 启动模式,执行startActivity(new Intent(AActivity.this,AActivity.class)跳转后栈里面依旧只有一个实例,如果现在按返回键程序将直接退出。也就是说AActivity 已经被启动,并且处于历史栈的栈顶,就不会创建新的AActivity实例,而是复用这个已经开启的Activity。

查看手机activity堆栈信息:adb -d shell dumpsys activity

Running activities (most recent first):

TaskRecord{2371f8cf #584 A=com.wong.testlifecycle U=0 sz=1}

Run #4: ActivityRecord{2aa37034 u0 com.wong.testlifecycle/.AActivity t584}

但如果AActivity不是在栈顶,那么就会创建新实例:假设跳转顺序为AActivity->BActivity->CActivity->AActivity,此时AActivity实例就不是在栈顶了,就会创建新实例。再看手机的activity栈信息:adb -d shell dumpsys activity

Running activities (most recent first):

TaskRecord{b6a3acc #585 A=com.wong.testlifecycle U=0 sz=4}

Run #7: ActivityRecord{137609dc u0 com.wong.testlifecycle/.AActivity t585}

Run #6: ActivityRecord{2eb74062 u0 com.wong.testlifecycle/.CActivity t585}

Run #5: ActivityRecord{b69ddac u0 com.wong.testlifecycle/.BActivity t585}

Run #4: ActivityRecord{35b621a2 u0 com.wong.testlifecycle/.AActivity t585}

再查看手机activity的堆栈信息: adb -d shell dumpsys activity -p com.wong.testlifecycle,发现它们是同一个任务栈里的。

Stack #1:

Task id #589

TaskRecord{3a2a4ae8 #589 A=com.wong.testlifecycle U=0 sz=4}

Hist #3: ActivityRecord{213a49b3 u0 com.wong.testlifecycle/.AActivity t589}

Hist #2: ActivityRecord{27cfaab1 u0 com.wong.testlifecycle/.CActivity t589}

Hist #1: ActivityRecord{2de96172 u0 com.wong.testlifecycle/.BActivity t589}

Hist #0: ActivityRecord{363e9d5e u0 com.wong.testlifecycle/.AActivity t589}

由查看手机activity栈信息来看,确实,在singleTop下,不是栈顶就会创建新实例

3、singleTask

对于“singleTask”启动模式的acitvity,如果这个实例已经存在 ,intent就会通过onNewIntent传递到这个Activity,并且将栈中该activity之上的activity清除(销毁过程会调用Activity生命周期回调);否则Activity实例将被创建。

这个对业务流程环节多的app很有帮助。比如:在手机上办理信用卡时,要填写很多信息,过程当中会链式打开很多个activity页面,在提交后,就跳到首页上去,按返回键时也不会出现以前填写信息的页面这种奇怪现象,怎么做到的呢?用singleTask就可以完美解决这个问题了。

假设有这样一个跳转:假设跳转顺序为AActivity->BActivity->CActivity->AActivity。要求是从最后一个页面返回到第一个页面且按返回键时,不会出现中间过程的页面。我们设置AActivity的启动模式设为singleTask 。

查看手机activity的堆栈信息:wong@wong-computer:~$ adb -d shell dumpsys activity,发现 BActivity,CActivity 都被弹出栈了,只剩下第一个页面,符合要求:

Running activities (most recent first):

TaskRecord{35f4cc20 #607 A=com.wong.testlifecycle U=0 sz=1}

Run #3: ActivityRecord{11bcd79d u0 com.wong.testlifecycle/.AActivity t60

4、singleInstance

对于singleInstance 启动模式的Activity,是其所在的栈的唯一activity,它会每次都被重用,而且系统是不会在启动模式singleInstance 的activity的task栈中启动任何其他的activity,任何从这个activity启动的activity都会在其他的栈中被打开。

假设有这样一个跳转:AActivity->BActivity->CActivity->AActivity。AActivity的启动模式设为singleInstance 。

查看手机activity的堆栈的信息: adb -d shell dumpsys activity -p com.wong.testlifecycle,发现singleInstance 启动模式的Activity是独占一个任务栈里的,任何从这个AActivity 启动的activity都会在其他的栈中被打开,而且 AActivity是可重用的,证据就是从CActivity跳转回 AActivity时,没有创建新实例,依旧用回原来那个。

Stack #1:

Task id #605

Hist #0: ActivityRecord{26b92869 u0 com.wong.testlifecycle/.AActivity t605}

Task id #606

Hist #1: ActivityRecord{1f049130 u0 com.wong.testlifecycle/.CActivity t606}

Hist #0: ActivityRecord{ca4e79c u0 com.wong.testlifecycle/.BActivity t606}

5、总结一下:

singleTop和standard几乎一样,使用singleTop的Activity也可以创建很多个实例。唯一不同的就是,如果调用的目标Activity已经位于调用者的Task的栈顶,则不创建新实例,而是使用当前的这个Activity实例,并调用这个实例的onNewIntent方法,Intent就会被传到这个地方来。

singleTop的使用场景比较少,例子比如用户已经在当前activity,用户点击一条推送消息之后也需要跳转到当前activity,那么为了避免activity的重复打开,则需要将该activity设置为singleTop并且复写onNewIntent即可。

如果是外部程序启动singleTop的Activity,表现都和standard一样。

singleInstance和singleTask类似,在系统中都只会存在一个实例,唯一的区别就是系统不会在singleInstance activity的task栈中启动任何其他的activity,singleInstance activity栈中仅仅只能有该activity的实例,其他任何从这个activity启动的activity都会在其他的栈中被打开。

最后,说一说如何设置activity的启动模式的方法,在Manifest.xml中的activity上用android:launchMode=””配置,launchMode的取值:standard、singleTop、singleInstance、singleTask:

<activity

android:name=".BActivity"

android:launchMode="singleInstance"/>

上一篇:Android学习
下一篇:Android常用面试题
选择城市和中心
贵州省

广西省

海南省