如果您有任何疑问,可以在下面询问或输入您要寻找的!
创作者:anly_jun
连接:https://www.jianshu.com/p/c97688eb5056
引入上文生命期和launchMode详细介绍, Activity的生命期事实上比大家想像的繁杂得多.
文中关键根据案例, 来探寻下Activity的运行Intent Flag及其taskAffinity对生命期和Task/Back Stack的危害. 算作对生命期和launchMode的一个填补, 便于我们在开发设计全过程中灵便组成应用.
按照惯例, 大家先从一些官方网表述逐渐:
之上为官方网文本文档表述.
在探寻Activity之launchMode一文中大家也提及了事实上文本文档因为"破旧"沒有紧跟, 有一些表述是不科学的.
我们可以追随案例一起看下.
使用之前探寻生命期的Demo程序流程.
Github源代码详细地址
根据AActivity, BActivity, CActivity这三个Activity中间的自动跳转来开展intent flag的探寻.
要是没有独到之处, 默认设置A, B, C三个Activity的launchMode全是默认设置的standard方式.
试验目地是看看, 在当今系统软件沒有A案例时, 用FLAG_ACTIVITY_NEW_TASK来运行A是否会将A建立在独立的每日任务中.
BActivity.java中:
startActivity(new Intent(BActivity.this, AActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
生命期Log:
Task/Back Stack信息内容:
Stack #1 mStackId=3:
Task id #35
* TaskRecord{42b60ae0 #35 A=com.anly.samples U=0 sz=3}
numActivities=3 rootWasReset=false userId=0 mTaskType=0 numFullscreen=3 mOnTopOfHome=true
affinity=com.anly.samples
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.anly.samples/.MainActivity}
realActivity=com.anly.samples/.MainActivity
Activities=[ActivityRecord{4285c1b0 u0 com.anly.samples/.MainActivity t35},
ActivityRecord{42decc00 u0 com.anly.samples/.activity.BActivity t35},
ActivityRecord{4376b9e8 u0 com.anly.samples/.activity.AActivity t35}]
能够见到:
B以FLAG_ACTIVITY_NEW_TASK运行A, A依然和B处于同一个Task中.
试验目地是想认证下官方网文本文档对FLAG_ACTIVITY_NEW_TASK的表述, 在A案例早已存有的状况下, 以FLAG_ACTIVITY_NEW_TASK运行A会产生哪些.
生命期Log:
Task/Back Stack信息内容:
Stack #1 mStackId=2:
Task id #34
* TaskRecord{42bfb088 #34 A=com.anly.samples U=0 sz=4}
numActivities=4 rootWasReset=false userId=0 mTaskType=0 numFullscreen=4 mOnTopOfHome=true
affinity=com.anly.samples
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.anly.samples/.MainActivity}
realActivity=com.anly.samples/.MainActivity
Activities=[ActivityRecord{42568318 u0 com.anly.samples/.MainActivity t34},
ActivityRecord{42725050 u0 com.anly.samples/.activity.AActivity t34},
ActivityRecord{42dab240 u0 com.anly.samples/.activity.BActivity t34},
ActivityRecord{42e293f8 u0 com.anly.samples/.activity.AActivity t34}]
能够见到:
1, 在B运行A以前, Task #34中原本就会有A, 可是B加FLAG_ACTIVITY_NEW_TASK运行A时, A仍未器重, 只是在本Task #34中在这里建立了一个A的案例. (这一点和文本文档叙述不一致)
2, 这时Task #34中的Activity案例为ABA.
3, 可是假如A的lunchMode是singleTask得话, 如lunchMode一文2.2.3所显示, 这时应当消毁A之上的案例, Task中只剩余A.
4, 综上所述, FLAG_ACTIVITY_NEW_TASK并不等同于与singleTask. 且FLAG_ACTIVITY_NEW_TASK觉得并且为起功效(在A早已存有一个案例的状况下).
BActivity运行B时加:
startActivity(new Intent(BActivity.this, BActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP));
生命期Log:
Task/Back Stack信息内容:
Stack #1 mStackId=6:
Task id #38
* TaskRecord{43665a30 #38 A=com.anly.samples U=0 sz=3}
numActivities=3 rootWasReset=true userId=0 mTaskType=0 numFullscreen=3 mOnTopOfHome=true
affinity=com.anly.samples
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.anly.samples/.MainActivity}
realActivity=com.anly.samples/.MainActivity
Activities=[ActivityRecord{42bbfea0 u0 com.anly.samples/.MainActivity t38},
ActivityRecord{433b6130 u0 com.anly.samples/.activity.AActivity t38},
ActivityRecord{4324ef18 u0 com.anly.samples/.activity.BActivity t38}]
能够见到:
1, B多路复用了, 根据onNewIntent, 走onResume步骤, 多路复用以前的B案例.
2, 这时Task #38中的Activity案例为AB.
试验目地是为了更好地看看A是否会器重, 且B是否会被Clear.
BActivity运行A的编码:
startActivity(new Intent(BActivity.this, AActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
生命期Log:
Task/Back Stack信息内容:
Stack #1 mStackId=7:
Task id #39
* TaskRecord{4274e020 #39 A=com.anly.samples U=0 sz=2}
numActivities=2 rootWasReset=false userId=0 mTaskType=0 numFullscreen=2 mOnTopOfHome=true
affinity=com.anly.samples
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.anly.samples/.MainActivity}
realActivity=com.anly.samples/.MainActivity
Activities=[ActivityRecord{42742598 u0 com.anly.samples/.MainActivity t39},
ActivityRecord{4274eb28 u0 com.anly.samples/.activity.AActivity t39}]
能够见到:
1, A并沒有器重, 只是新创建了一个案例. 这一和文本文档是一致的, 参照FLAG_ACTIVITY_CLEAR_TOP定义第二点.
2, B被消毁了(Clear Top).
3, 这时Task #39中仅有A(一个新的A).
之上是简易应用, 随后具体情景中会出现许多组成应用Intent Flag及其Intent Flag与taskAffinity融合应用的状况. 在其中官方网文本文档就提及了:
FLAG_ACTIVITY_CLEAR_TOP 一般与 FLAG_ACTIVITY_NEW_TASK 融合应用。一起应用时,根据这种标示,能够寻找别的每日任务中的目前 Activity,并将其放进可从这当中回应 Intent 的部位。
下边大家来试验下这类组成:
实行A -> B -> A, 在其中B运行A时, Intent flag加FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASK
B运行A的编码:
startActivity(new Intent(BActivity.this, AActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK));
生命期Log:
Task/Back Stack信息内容:
Stack #1 mStackId=8:
Task id #40
* TaskRecord{429c96b0 #40 A=com.anly.samples U=0 sz=2}
numActivities=2 rootWasReset=false userId=0 mTaskType=0 numFullscreen=2 mOnTopOfHome=true
affinity=com.anly.samples
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.anly.samples/.MainActivity}
realActivity=com.anly.samples/.MainActivity
Activities=[ActivityRecord{427907d0 u0 com.anly.samples/.MainActivity t40},
ActivityRecord{42dd24b8 u0 com.anly.samples/.activity.AActivity t40}]
能够见到:
1, 結果和2.3.1独立应用Intent.FLAG_ACTIVITY_CLEAR_TOP是一样的.
有2.1.1, 2.1.2及其2.4.1这三个包括Intent.FLAG_ACTIVITY_NEW_TASK的试验, 能够见到, 字面Intent.FLAG_ACTIVITY_NEW_TASK的意思是在新的task运行Activity, 殊不知实际上, 新Activity還是在原先的task上建立的.
这儿必须明确提出官方网站有关taskAffinity的表述了:
taskAffinity标示Activity优先选择归属于哪一个task. 默认设置状况下, 同一运用中的全部 Activity 彼此之间关系. 因而, 默认设置状况下, 同一运用中的全部 Activity 优先选择坐落于同样每日任务中.
taskAffinity在二种状况下能起功效:
— 运行 Activity 的 Intent 包括 FLAG_ACTIVITY_NEW_TASK 标示.
— Activity 将其 allowTaskReparenting 特性设定为 “true”.
使我们来融合taskAffinity做下试验:
设定A和B不一样的taskAffinity, 实行Main -> A -> B -> A -> B -> A, 在其中B运行A应用FLAG_ACTIVITY_NEW_TASK
为何要实行2次B -> A? 大家追随试验結果, 稍候看来.
设定A的taskAffinity为com.anly.aactivity, B默认设置(包名).
B运行A:
startActivity(new Intent(BActivity.this, AActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
生命期Log:
Task/Back Stack信息内容:
Stack #1 mStackId=10:
Task id #44
* TaskRecord{43085768 #44 A=com.anly.aactivity U=0 sz=2}
numActivities=2 rootWasReset=false userId=0 mTaskType=0 numFullscreen=2 mOnTopOfHome=false
affinity=com.anly.aactivity
intent={flg=0x10000000 cmp=com.anly.samples/.activity.AActivity}
realActivity=com.anly.samples/.activity.AActivity
Activities=[ActivityRecord{4303fe00 u0 com.anly.samples/.activity.AActivity t44}, ActivityRecord{4324bb10 u0 com.anly.samples/.activity.BActivity t44}]
Task id #43
* TaskRecord{426d0a78 #43 A=com.anly.samples U=0 sz=3}
numActivities=3 rootWasReset=true userId=0 mTaskType=0 numFullscreen=3 mOnTopOfHome=true
affinity=com.anly.samples
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.anly.samples/.MainActivity}
realActivity=com.anly.samples/.MainActivity
Activities=[ActivityRecord{4256ae80 u0 com.anly.samples/.MainActivity t43},
ActivityRecord{4372db08 u0 com.anly.samples/.activity.AActivity t43},
ActivityRecord{4273f478 u0 com.anly.samples/.activity.BActivity t43}]
能够见到:
1, Stack #1中有两个Task, #43(affinity=com.anly.samples)和#44(affinity=com.anly.aactivity).
2, 第一轮Main -> A -> B时, 再Task #43中造成了Main,A,B三个Activity案例.
3, 然后B -> A时, A在一个新的Task #44中建立了新的A案例.
4, 随后A -> B, 由于B不用一切主要参数(运行方式, affinity, flag等), B会建立在运行他的Activity也就是A所属的Task.
5, 这时Task #44中就拥有A, B.
6, 再度在B中点一下运行A(带上Intent.FLAG_ACTIVITY_NEW_TASK)时. 并沒有一切反映.
怎么会发生第六点叙述的那样的难题呢?
我了解:
这时B运行A, 由于带上Intent.FLAG_ACTIVITY_NEW_TASK, 且A的taskAffnity为"com.anly.aactivity". 系统软件会在affinity=com.anly.aactivity的Task中找是否有早已存有的A的案例, 发觉Task #44中有. 因此, 想器重A. 殊不知并沒有能消毁B, 让A弹出窗口接受新的Intent.
所以说, 这类状况下, Intent.FLAG_ACTIVITY_NEW_TASK务必融合Intent.FLAG_ACTIVITY_CLEAR_TOP来一起用.
使我们再做一个试验认证下念头.
设定A和B不一样的taskAffinity, 实行Main -> A -> B -> A -> B -> A, 在其中B运行A应用FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_CLEAR_TOP
A的affinity還是设成com.anly.aactivity, B默认设置.
B运行A的编码:
startActivity(new Intent(BActivity.this, AActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP));
生命期Log:
Task/Back Stack信息内容:
Stack #1 mStackId=11:
Task id #46
* TaskRecord{4338bc08 #46 A=com.anly.aactivity U=0 sz=1}
numActivities=1 rootWasReset=false userId=0 mTaskType=0 numFullscreen=1 mOnTopOfHome=false
affinity=com.anly.aactivity
intent={flg=0x14000000 cmp=com.anly.samples/.activity.AActivity}
realActivity=com.anly.samples/.activity.AActivity
Activities=[ActivityRecord{42d88890 u0 com.anly.samples/.activity.AActivity t46}]
Task id #45
* TaskRecord{42eee4d0 #45 A=com.anly.samples U=0 sz=3}
numActivities=3 rootWasReset=false userId=0 mTaskType=0 numFullscreen=3 mOnTopOfHome=true
affinity=com.anly.samples
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.anly.samples/.MainActivity}
realActivity=com.anly.samples/.MainActivity
Activities=[ActivityRecord{42ed9690 u0 com.anly.samples/.MainActivity t45}, ActivityRecord{42e507b8 u0 com.anly.samples/.activity.AActivity t45}, ActivityRecord{42714cd0 u0 com.anly.samples/.activity.BActivity t45}]
能够见到:
果真, 这时第二次B -> A, 有实际效果了, 自动跳转到A了.
殊不知, 大家发觉, 尽管Task #46中只有一个A(B被clear top,消毁了). 殊不知A并并不是器重的, 只是先消毁了解来的A案例, 复建了一个A案例.
参照有关定义Intent.FLAG_ACTIVITY_CLEAR_TOP的第二点表述, 确实是那样, 由于A是默认设置的standard方式, 因此 务必新创建案例.
到此, 大家有关Intent flag和taskAffinity的试验完毕, 大家看来下有关结果:
我是这篇文章的创作本人 请您把文章删了 ...
评论于 华为eNSP最稳定的装法