大家好,今天给各位分享深入解析Android应用开发:Activity生命周期与启动模式的秘密的一些知识,其中也会对进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!
* A --B(单顶)
* 再次启动B后的生命周期:
onPause --onNewIntent --onResume 如果要启动的Activity不在栈顶,则与标准模式完全一致;
* A --B(单顶) --C
* 再次启动B回栈:
A --B(SingleTop) --C --B(SingleTop)
SingleTask:栈内复用模式
特别注意该模式下配置的Activity不会在新的任务栈中,但如果要启动的Activity已经在栈中,它会clearTop,把自己放到栈顶;
* A --B(单任务) --C
TaskRecord{ed93b47 #259 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=4}
运行#3: ActivityRecord{c1f4817 u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t259}
运行#2: ActivityRecord{59e1a72 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t259}
运行#1: ActivityRecord{d7ae33c u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t259}
* 再次启动post-B任务栈:
A --B(单任务)
此时C将被销毁
此时B的生命周期:onPause --onNewIntent --onResume
TaskRecord{ed93b47 #259 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=3}
运行#2: ActivityRecord{59e1a72 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t259}
运行#1: ActivityRecord{d7ae33c u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t259}
SingleInstance:单实例模式
该模式下的Activity 只能位于独立任务栈中;
* A --B(单实例) --C
此时A和C在同一个任务栈上,B在独立的任务栈上;
TaskRecord{c37f244 #253 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=3}
运行#3: ActivityRecord{8d06468 u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t253}
TaskRecord{10b2e56 #257 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=1}
运行#2: ActivityRecord{eeb0317 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t257}
TaskRecord{c37f244 #253 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=3}
运行#1: ActivityRecord{e25c532 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t253}
* 再次启动B回栈:
A --C --B(单实例)
此时B调整为前台任务栈,A、C的任务栈调整为后台任务栈;
此时B的生命周期:onPause --onNewIntent --onResume
TaskRecord{10b2e56 #257 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=1}
运行#3: ActivityRecord{eeb0317 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t257}
TaskRecord{c37f244 #253 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=3}
运行#2: ActivityRecord{8d06468 u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t253}
运行#1: ActivityRecord{e25c532 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t253}
怎么确定Activity位于哪个任务栈
除SingleInstance 模式下的Activity 外,所有其他模式下的Activity 都会添加到默认任务堆栈中,默认任务堆栈taskAffinity 是包名;
可以通过指定taskAffinity让activity运行在特定的任务栈中,必须与FLAG_ACTIVITY_NEW_TASK结合才能生效;
除SingleInstance 模式的Activity 外,启动普通Activity 都会添加到与启动此Activity 所用的Activity 相同的任务堆栈中。除非同时指定taskAffinity和FLAG_ACTIVITY_NEW_TASK,否则会运行在与taskAffinity同名的任务栈中;
* A --B(taskAffinity=test.gcoder.io.newtask 标志=FLAG_ACTIVITY_NEW_TASK)
TaskRecord{99b9ba5 #269 A=test.gcoder.io.newtask, isShadow:false U=0 sz=1}
运行#2: ActivityRecord{5ba0ca2 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t269}
TaskRecord{ab040b2 #267 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=2}
运行#1: ActivityRecord{1ddfc0 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t267}
* A --B(taskAffinity=test.gcoder.io.newtask flag=FLAG_ACTIVITY_NEW_TASK)--C
TaskRecord{99b9ba5 #269 A=test.gcoder.io.newtask, isShadow:false U=0 sz=2}
运行#3: ActivityRecord{199ec49 u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t269}
运行#2: ActivityRecord{5ba0ca2 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t269}
TaskRecord{ab040b2 #267 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=2}
运行#1: ActivityRecord{1ddfc0 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t267}
Context对Activity任务栈的影响
经过比较,使用Activity Context启动Activity和使用Application Context启动Activity没有区别,都在相同的任务栈;
开始使用活动上下文
* A --B(FLAG_ACTIVITY_NEW_TASK)
TaskRecord{6a79d7e #261 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=3}
运行#2: ActivityRecord{8754172 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t261}
运行#1: ActivityRecord{43b510 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t261}
* A --B(FLAG_ACTIVITY_NEW_TASK)--C
TaskRecord{6a79d7e #261 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=4}
运行#3: ActivityRecord{4095453 u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t261}
运行#2: ActivityRecord{8754172 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t261}
运行#1: ActivityRecord{43b510 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t261} 开始使用应用程序上下文
* A --B(FLAG_ACTIVITY_NEW_TASK)
TaskRecord{eb6f24d #262 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=3}
运行#2: ActivityRecord{215a79a u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t262}
运行#1: ActivityRecord{7e22051 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t262}
* A --B(FLAG_ACTIVITY_NEW_TASK)--C
TaskRecord{eb6f24d #262 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=4}
运行#3: ActivityRecord{dac68e6 u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t262}
运行#2: ActivityRecord{215a79a u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t262}
运行#1: ActivityRecord{7e22051 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t262}
* 再次启动B后:A --B(FLAG_ACTIVITY_NEW_TASK) --C --B(FLAG_ACTIVITY_NEW_TASK)
TaskRecord{eb6f24d #262 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=5}
运行#4: ActivityRecord{2ec8ea1 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t262}
运行#3: ActivityRecord{c30b233 u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t262}
运行#2: ActivityRecord{e88653e u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t262}
运行#1: ActivityRecord{177c4a8 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t262}
Flag对Activity任务栈的影响
FLAG_ACTIVITY_NEW_TASK
仅添加此Flag 的Activity 不会添加到新的任务堆栈中。此时与SingleTask无关,不具备SingleTask独有的同任务栈特性和clearTop特性;该标志可用于非活动类型。启动新活动的上下文;该Flag与其他Flag混合使用会产生不同的效果;
FLAG_ACTIVITY_MULTIPLE_TASK
该Flag一般不单独使用,需要与FLAG_ACTIVITY_NEW_TASK配合使用;
FLAG_ACTIVITY_MULTIPLE_TASK | FLAG_ACTIVITY_NEW_TASK
单独使用时,将检索现有任务堆栈。如果启动的Activity对应的任务栈存在,则不会创建。如果不存在,则会创建一个新的任务栈。
同时使用时,会强制创建一个新的任务栈,并将启动的Activity放入新的任务栈中。使用此活动启动的后续标准模式活动将在此堆栈而不是默认堆栈中运行;
* A --B(FLAG_ACTIVITY_MULTIPLE_TASK|FLAG_ACTIVITY_NEW_TASK)
TaskRecord{4144b1a0 #6 A test.gcoder.io.testactivity U 0}
运行#3: ActivityRecord{413fd7a8 test.gcoder.io.testactivity/.BActivity}
TaskRecord{41548560 #5 A test.gcoder.io.testactivity U 0}
运行#2: ActivityRecord{41562330 test.gcoder.io.testactivity/.AActivity}
* A --B(FLAG_ACTIVITY_MULTIPLE_TASK|FLAG_ACTIVITY_NEW_TASK) --C
TaskRecord{4144b1a0 #6 A test.gcoder.io.testactivity U 0}
运行#4: ActivityRecord{41604278 test.gcoder.io.testactivity/.CActivity}
运行#3: ActivityRecord{413fd7a8 test.gcoder.io.testactivity/.BActivity}
TaskRecord{41548560 #5 A test.gcoder.io.testactivity U 0}
运行#2: ActivityRecord{41562330 test.gcoder.io.testactivity/.AActivity}
* A --B(FLAG_ACTIVITY_MULTIPLE_TASK|FLAG_ACTIVITY_NEW_TASK) --C --B(FLAG_ACTIVITY_MULTIPLE_TASK|FLAG_ACTIVITY_NEW_TASK)
TaskRecord{41434a90 #7 A test.gcoder.io.testactivity U 0}
运行#5: ActivityRecord{413a6710 test.gcoder.io.testactivity/.BActivity}
TaskRecord{4144b1a0 #6 A test.gcoder.io.testactivity U 0}
运行#4: ActivityRecord{41604278 test.gcoder.io.testactivity/.CActivity}
运行#3: ActivityRecord{413fd7a8 test.gcoder.io.testactivity/.BActivity}
TaskRecord{41548560 #5 A test.gcoder.io.testactivity U 0}
Run #2: ActivityRecord{41562330 test.gcoder.io.testactivity/.AActivity}
FLAG_ACTIVITY_SINGLE_TOP
与SingleTop 相同
FLAG_ACTIVITY_CLEAR_TOP
单独使用该Flag 时,如果要启动的Activity 存在于对应的任务栈中,则该Activity 之上的所有Activity任务栈中待启动的Activity会被清空,待启动的Activity会先销毁再重新创建;
单独使用该Flag时,如果启动的Activity在对应的任务栈中不存在,则会创建它并添加到对应的任务栈中;
* A --B(FLAG_ACTIVITY_CLEAR_TOP) --C
TaskRecord{166703a #289 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=4}
运行#3: ActivityRecord{374b0ff u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t289}
运行#2: ActivityRecord{15086 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t289}
运行#1: ActivityRecord{da843b0 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t289}
* 再次启动B(FLAG_ACTIVITY_CLEAR_TOP)
* 生命周期:C会被销毁,B会先销毁再创建
C(暂停时)
B(onDestroy)--B(onCreate)--B(onStart)--B(onResume)
C(onStop)--C(onDestroy)
TaskRecord{166703a #289 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=3}
运行#2: ActivityRecord{6420128 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t289}
运行#1: ActivityRecord{da843b0 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t289}
FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK
如果要启动的Activity在对应的任务栈中,则任务栈顶部的所有Activity都会被销毁并通过onNewIntent( ) 将此Intent 传递给已恢复的Activity 实例(现在位于顶部),而不是启动Activity 的新实例;
如果启动的Activity不在对应的任务栈中,则创建一个新的任务栈,创建该Activity并将其添加到新的任务栈中;
* A --B (FLAG_ACTIVITY_MULTIPLE_TASK | FLAG_ACTIVITY_CLEAR_TOP)
TaskRecord{413377c #286 A=test.gcoder.io.newtask, isShadow:false U=0 sz=1}
运行#2: ActivityRecord{a58be9a u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t286}
TaskRecord{cfe9805 #285 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=2}
运行#1: ActivityRecord{b5a1c24 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t285}
* A --B (FLAG_ACTIVITY_MULTIPLE_TASK | FLAG_ACTIVITY_CLEAR_TOP) --C
TaskRecord{413377c #286 A=test.gcoder.io.newtask, isShadow:false U=0 sz=2}
运行#3: ActivityRecord{9f7c8df u0 test.gcoder.io.testactivity/.CActivity, isShadow:false t286}
运行#2: ActivityRecord{a58be9a u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t286}
TaskRecord{cfe9805 #285 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=2}
运行#1: ActivityRecord{b5a1c24 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t285}
* 再次启动B (FLAG_ACTIVITY_MULTIPLE_TASK | FLAG_ACTIVITY_CLEAR_TOP)
* 生命周期:C会被销毁,B会先销毁再创建
C(暂停时)
B(onDestroy)--B(onCreate)--B(onStart)--B(onResume)
C(onStop)--C(onDestroy)
TaskRecord{413377c #286 A=test.gcoder.io.newtask, isShadow:false U=0 sz=1}
运行#2: ActivityRecord{ff16c57 u0 test.gcoder.io.testactivity/.BActivity, isShadow:false t286}
TaskRecord{cfe9805 #285 A=test.gcoder.io.testactivity, isShadow:false U=0 sz=2}
运行#1: ActivityRecord{b5a1c24 u0 test.gcoder.io.testactivity/.AActivity, isShadow:false t285} 注意:如果指定Activity 的启动模式为"standard",则该Activity 也会从堆栈中移除并在其位置启动处理传入意图的新实例。这是因为当启动模式为“标准”时,总会为新的Intent 创建一个新实例。
好了,关于深入解析Android应用开发:Activity生命周期与启动模式的秘密和的问题到这里结束啦,希望可以解决您的问题哈!
【深入解析Android应用开发:Activity生命周期与启动模式的秘密】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
Android开发真能考验耐心!这段时间一直被Activity的生命周期绕着转。
有7位网友表示赞同!
看了这个标题,感觉可以彻底搞明白Android启动模式了
有7位网友表示赞同!
之前对这些概念还不太理解,现在正好想深 dive一下
有20位网友表示赞同!
分享一些还没听过的点吗?我可就喜欢这个 "你不知道的那些事"
有18位网友表示赞同!
感觉Android开发确实有很多细节需要注意啊,希望这篇文章能让我更了解
有11位网友表示赞同!
每次调试app的时候都觉得生命周期搞不懂是主要原因!
有8位网友表示赞同!
最近项目用到了一些复杂的启动模式,希望能在这篇文章中找到答案
有18位网友表示赞同!
我感觉Android的开发文档很难理解,期待这篇文章能用更通俗易懂的方式解释
有5位网友表示赞同!
真希望学完之后能不再看错那些日志信息了!
有19位网友表示赞同!
我特别想了解不同启动模式下的内存优化方法。
有8位网友表示赞同!
要是我开发的 app 出现问题,那这些“你不知道的事”会不会是我的罪魁祸首?
有7位网友表示赞同!
还是挺好奇各种启动模式之间的关系,这篇文章应该能解答一下吧!
有19位网友表示赞同!
期待作者分享一些实践经验和技巧!
有7位网友表示赞同!
希望这篇文章能让我更清楚地理解Activity的生命周期管理
有18位网友表示赞同!
每次做题的时候都感觉生命周期的代码好烦人~ 希望能在这篇文中找到解决方案
有7位网友表示赞同!
我觉得这个标题很有吸引力,应该会讲到一些比较隐蔽的知识点!
有14位网友表示赞同!
要是不了解启动模式,会不会就无法开发出流畅的用户体验呢?
有9位网友表示赞同!
看来我的Android学习之路还有很多地方需要继续努力!
有15位网友表示赞同!