Activity启动模式及标记位
来源:互联网 发布:加工中心编程实例 编辑:程序博客网 时间:2024/05/17 09:47
Activity启动模式
在说activity启动模式之前,我们要先了解activity栈的概念。activity任务栈是一个“后进先出”的栈结构。即启动一个新activity实例时会将其压入栈顶,当该activity按返回键退出时,其实例会从任务栈中出栈。任务栈分为前台任务栈和后台任务栈,后台任务栈中的activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。
activity的启动模式就是配合栈的工作原理,来满足日常的业务需要。activity启动的模式有四种:standard、singleTop、singleTask和singleInstance。standard就是activity默认的启动模式。
standard:标准模式(默认模式)
这种模式下的activity每次启动都会创建一个新的实例,并且不管该实例是否在任务栈内存在都会压栈。如果activityA和activityB都是标准模式,activityA启动了activityB,这时候栈顶是activityB,下面是activityA。
标准模式的activity默认会进入启动它的activity所属的任务栈中,非activity类型的Context若要启动该activity,需要加上标记位FLAG_ACTIVITY_NEW_TASK,即重新为其创建一个新的任务栈。此标志位的启动模式实际上是以singleTask模式启动的。(后续会解释,这里先跳过标记位知识点)
命令行查看栈内activity列表信息
例:在同一APP内且没有标记位情况下,执行跳转activityA——activityB——activityC——activityA,他们都是标准模式。理论上栈内应为ABCA。
命令行执行:
adb shell dumpsys activity
命令行查询栈信息时里面的信息非常多且杂,这里主要看
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
该行下面的信息即可,即 Hist #3:—— Hist #2:—— Hist #1:—— Hist #0:,栈内从上到下的的显示顺序,Hist #3位于栈顶。
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)Display #0 (activities from top to bottom): Stack #1: Task id #319 TaskRecord{22fe5578 #319 A=com.jzf.myactivity U=0 sz=4} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.jzf.myactivity/.ActivityA } Hist #3: ActivityRecord{38af6616 u0 com.jzf.myactivity/.ActivityA t319} Intent { cmp=com.jzf.myactivity/.ActivityA } ProcessRecord{37252451 3045:com.jzf.myactivity/u0a58} Hist #2: ActivityRecord{29295492 u0 com.jzf.myactivity/.ActivityC t319} Intent { cmp=com.jzf.myactivity/.ActivityC } Hist #1: ActivityRecord{4dcc45c u0 com.jzf.myactivity/.ActivityB t319} Intent { cmp=com.jzf.myactivity/.ActivityB } Hist #0: ActivityRecord{2bc3c1f6 u0 com.jzf.myactivity/.ActivityA t319} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.jzf.myactivity/.ActivityA } Running activities (most recent first): TaskRecord{22fe5578 #319 A=com.jzf.myactivity U=0 sz=4} Run #0: ActivityRecord{38af6616 u0 com.jzf.myactivity/.ActivityA t319} mResumedActivity: ActivityRecord{38af6616 u0 com.jzf.myactivity/.ActivityA t319}
也能从 Running activities (most recent first):该行下面看到该栈内的activity数量sz=4,以及位于栈顶的activityA。
singleTask:栈内复用模式
这是一种单实例模式,只要该模式的activity在一个栈中存在,多次启动此activity都不会创建实例。singleTask模式默认具有clearTop效果,会导致栈内所有在此activity上的所有activity全部出栈。这种模式下,系统会回调此activity的onNewIntent方法,不会重新执行该activity的onCreate和onStart方法。
例:在同一APP内且没有标记位情况下,执行跳转activityA——activityB——activityC——activityB,activityA和activityC是标准模式,activityB是singleTask模式。理论情况下结果应该是AB,B位于栈顶。
activityC跳转到activityB的log日志如下:
D/ActivityC: onPauseD/ActivityB: onNewIntentD/ActivityB: onRestartD/ActivityB: onStartD/ActivityB: onResumeD/ActivityC: onStopD/ActivityC: onDestroyD/ActivityC: ————————————————
命令行查询栈部分信息如下:
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)Display #0 (activities from top to bottom): Stack #1: Task id #321 TaskRecord{280e2df3 #321 A=com.jzf.myactivity U=0 sz=2} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.jzf.myactivity/.ActivityA } Hist #1: ActivityRecord{2beb98ab u0 com.jzf.myactivity/.ActivityB t321} Intent { flg=0x10000000 cmp=com.jzf.myactivity/.ActivityB } ProcessRecord{1cfbcab0 3775:com.jzf.myactivity/u0a58} Hist #0: ActivityRecord{1b45261d u0 com.jzf.myactivity/.ActivityA t321} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.jzf.myactivity/.ActivityA } Running activities (most recent first): TaskRecord{280e2df3 #321 A=com.jzf.myactivity U=0 sz=2} Run #0: ActivityRecord{2beb98ab u0 com.jzf.myactivity/.ActivityB t321} mResumedActivity: ActivityRecord{2beb98ab u0 com.jzf.myactivity/.ActivityB t321}
如上所述,Hist #1: 是ActivityB,Hist #0:是ActivityA,整个任务栈有两个activity,ActivityB位于栈顶。
这就解释了activityA——activityB——activityC——activityB,当activityC——activityB时会复用栈内已有的activityB实例,并清空原先位于上面的activityC。
singleTop:栈顶复用模式
如果此模式的activity位于任务栈的栈顶(复用的前提必须满足这个条件哦~),那么此activity不会被重新创建,同时它的onNewIntent方法会被回调。需要注意的是该activity的onCreate,onStart不会被系统调用,因为它并没有发生改变。
singleInstance:单实例模式
简单理解就是这是一种加强型的singleTask模式,除了具备singleTask的所有特性外,还有一点是具备此模式的activity只能单独位于一个任务栈中。由于具备singleTask的栈内复用特性,后续的启动该activity均不会创建新的activity,除非这个任务栈被销毁了。
常用标记位
activity的启动,通常是在AndroidMenifest.xml文件中设置启动模式,但有些时候也会用到标记位。这里简单列举下常用的标记位及其用法,其余的各位完全可以在源码中了解的~
注意:加标记位的启动模式优先级比在AndroidMenifest.xml文件中指定的启动模式。
FLAG_ACTIVITY_NEW_TASK
此标记位的意义在于,在Activity上下文之外启动Activity需要给Intent设置FLAG_ACTIVITY_NEW_TASK标志,系统会为这个Activity指定或分配一个任务栈。
此模式为activity指定“singleTask”启动模式,其效果和在AndroidMenifest.xml文件中指定该启动模式相同。设置此状态,首先会查找是否存在和被启动的Activity具有相同的亲和性的任务栈(即TaskAffinity,注意同一个应用程序中的activity的亲和性一样)。如果有,就直接把这个栈整体移动到前台,并保持栈中的状态不变,即栈中的activity顺序不变;如果没有,则新建一个栈来存放被启动的activity。
FLAG_ACTIVITY_CLEAR_TOP
清除包含此Activity的Task中位于该Activity实例之上的其他Activity实例。
案例:activityA——activityB——activityC——activityB,在启动activityB的时候单独加上
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
在activityC启动activityB时候打印部分log日志如下:
D/ActivityC: onPauseD/ActivityB: onDestroyD/ActivityB: ————————————————D/ActivityB: onCreateD/ActivityB: onStartD/ActivityB: onResumeD/ActivityC: onStopD/ActivityC: onDestroyD/ActivityC: ————————————————
FLAG_ACTIVITY_SINGLE_TOP
与launchMode=”singleTop”一样的效果。
若FLAG_ACTIVITY_CLEAR_TOP配合FLAG_ACTIVITY_SINGLE_TOP使用,则B不会销毁只销毁B以上实例,然后B 执行onNewIntent -> onStart。
案例:activityA——activityB——activityC——activityB,在启动activityB的时候加上两个标记位,在activityC启动activityB时候打印部分log日志如下:
D/ActivityC: onPauseD/ActivityB: onNewIntentD/ActivityB: onRestartD/ActivityB: onStartD/ActivityB: onResumeD/ActivityC: onStopD/ActivityC: onDestroyD/ActivityC: ————————————————
- Activity启动模式及标记位
- Activity的启动模式和标记位
- android-Activity 的启动模式和标记位
- Activity的启动模式和Intent标记位
- Activity---启动模式标志位
- Android Activity标记位
- Activity 生命周期及启动模式
- Activity应用及启动模式
- activity的启动模式和表示位
- Activity的启动模式与标志位
- 【Activity】Activity生命周期及启动模式
- 第六天 activity及activity启动模式
- Activity 四个启动模式和若干intent标记,应用场景。
- Android Activity的启动模式以及Intent的启动Activity的启动标记
- Activity生命周期启动方式及启动模式
- Activity 启动模式及Intent的Flags
- Activity启动模式及Intent传递对象
- Activity启动模式 及 Intent Flags
- HDU1172 猜数字
- 活动选择问题(贪心)
- MapReduce的容错机制
- 2017年3月3日,周结(二),几种UI控件的使用
- 02_文件配置与目录权限
- Activity启动模式及标记位
- 将整数按位逆置的算法设计为一个函数,函数名为reverse
- C++知识点14
- Android中的Uri
- java内部类
- Java文件上传与下载
- js事件总结之概述
- 413. Arithmetic Slices
- uva 439 Knight Moves 骑士移动 —— bfs