Activity的启动模式launchMode

1.launchMode具体介绍

Activity的启动模式launchMode_第1张图片

2.四种launchMode的区别

Activity的启动模式launchMode_第2张图片

3.任务栈的切换演示

假设:

有两个程序:App1、App2,包名为:App1 = com.example.malingyi.testtask1 App2 = com.chao.studydemoa

ActivityA属于App1、ActivityB属于App2;两个App都有MainActivity作为启动入口。

情况一:单一Task&默认的启动模式下,App切换时的Activity栈情况

启动模式:

ActivityA:standard

ActivityB:standard

App1、App2:MainActivity:standard

TaskAffinity:

都是默认情况下的TaskAffinity(包名)

初始化启动顺序:

Step1:启动App1:MainActivity——>ActivityA ;

Step2:启动App2:MainActivity——>ActivityB;

**栈顶Activity:**ActivityB

Activity栈:

App1.MainActivity——>App1.ActivityA——>App2.MainActivity——>App2.ActivityB

初始任务栈信息如下:

mResumedActivity: ActivityRecord{8cc836e u0 com.chao.studydemoa/.DemoActivityB t47}
mLastPausedActivity: ActivityRecord{83242e5 u0 com.chao.studydemoa/.MainActivity t47}
* Task{7479fe0 #47 type=standard A=10147:com.chao.studydemoa U=0 visible=true mode=fullscreen translucent=false sz=2} //task信息
task affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{83242e5 u0 com.chao.studydemoa/.MainActivity t47}, ActivityRecord{8cc836e u0 com.chao.studydemoa/.DemoActivityB t47}] //activity信息
mRootProcess=ProcessRecord{fe671ba 11315:com.chao.studydemoa/u0a147} //进程信息
taskId=47 rootTaskId=47
mLastPausedActivity: ActivityRecord{2803afa u0 com.chao.studydemo/.DemoActivityA t46}
* Task{b9933de #46 type=standard A=10146:com.chao.studydemo U=0 visible=false mode=fullscreen translucent=true sz=2}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{9697648 u0 com.chao.studydemo/.MainActivity t46}, ActivityRecord{2803afa u0 com.chao.studydemo/.DemoActivityA t46}]
mRootProcess=ProcessRecord{7a17ce1 11275:com.chao.studydemo/u0a146}
taskId=46 rootTaskId=46

(1)从App2.ActivityB启动App1.ActivityA

切换后任务栈:

* Task{7479fe0 #47 type=standard A=10147:com.chao.studydemoa U=0 visible=true mode=fullscreen translucent=false sz=3}
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{83242e5 u0 com.chao.studydemoa/.MainActivity t47}, ActivityRecord{8cc836e u0 com.chao.studydemoa/.DemoActivityB t47}, ActivityRecord{f31bd0c u0 com.chao.studydemo/.DemoActivityA t47}]
mRootProcess=ProcessRecord{fe671ba 11315:com.chao.studydemoa/u0a147}
* Task{b9933de #46 type=standard A=10146:com.chao.studydemo U=0 visible=false mode=fullscreen translucent=true sz=2}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{9697648 u0 com.chao.studydemo/.MainActivity t46}, ActivityRecord{2803afa u0 com.chao.studydemo/.DemoActivityA t46}]
mRootProcess=ProcessRecord{7a17ce1 11275:com.chao.studydemo/u0a146}

初始栈: App1.MainActivity——>App1.ActivityA——>App2.MainActivity——>App2.ActivityB

操作后的栈:App1.MainActivity——>App1.ActivityA——>App2.MainActivity——>App2.ActivityB——>App1.ActivityA

(2)接着上面,我们又从App1.ActivityA启动App2.ActivityB

任务栈信息:

* Task{7479fe0 #47 type=standard A=10147:com.chao.studydemoa U=0 visible=true mode=fullscreen translucent=false sz=4}
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{83242e5 u0 com.chao.studydemoa/.MainActivity t47}, ActivityRecord{8cc836e u0 com.chao.studydemoa/.DemoActivityB t47}, ActivityRecord{f31bd0c u0 com.chao.studydemo/.DemoActivityA t47}, ActivityRecord{b14af8f u0 com.chao.studydemoa/.DemoActivityB t47}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{fe671ba 11315:com.chao.studydemoa/u0a147}
* Task{b9933de #46 type=standard A=10146:com.chao.studydemo U=0 visible=false mode=fullscreen translucent=true sz=2}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{9697648 u0 com.chao.studydemo/.MainActivity t46}, ActivityRecord{2803afa u0 com.chao.studydemo/.DemoActivityA t46}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{7a17ce1 11275:com.chao.studydemo/u0a146}

初始栈: App1.MainActivity——>App1.ActivityA——>App2.MainActivity——>App2.ActivityB

操作后的栈:App1.MainActivity——>App1.ActivityA——>App2.MainActivity——>App2.ActivityB——>App1.ActivityA——>App2.ActivityB

同样,我们看到新启动的ActivityB,还是在原有的App2的Task栈中。

这里的到了两个结论:

standard模式下,Activity会重新创建一个新的实例,不论原有实例是否存在。

standard模式下,Activity会进入启动它的Activity所在的Task栈中,这个结论对于在启动其他App的Activity也成立。

情况二:单一Task&含有SingleTop的模式下,App切换时的Activity栈情况

启动模式:

ActivityA:singleTop

ActivityB:standard

App1、App2:MainActivity:standard

TaskAffinity:

都是默认情况下的TaskAffinity(包名)

初始化启动顺序:

Step1:启动App1:MainActivity——>ActivityA ;

Step2:启动App2:MainActivity——>ActivityB;

**栈顶Activity:**ActivityB

Activity栈:

App1.MainActivity——>App1.ActivityA——>App2.MainActivity——>App2.ActivityB

初始任务栈信息如下:

* Task{4c89ef1 #56 type=standard A=10147:com.chao.studydemoa U=0 visible=true mode=fullscreen translucent=false sz=2}
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{88e44b2 u0 com.chao.studydemoa/.MainActivity t56}, ActivityRecord{cbd889a u0 com.chao.studydemoa/.DemoActivityB t56}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{12dac03 15495:com.chao.studydemoa/u0a147}
* Task{424c9d7 #55 type=standard A=10146:com.chao.studydemo U=0 visible=false mode=fullscreen translucent=true sz=2}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{b0b3e00 u0 com.chao.studydemo/.MainActivity t55}, ActivityRecord{7b88443 u0 com.chao.studydemo/.DemoActivityA t55}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{4ad9639 15457:com.chao.studydemo/u0a146}

(1)从App2.ActivityB启动App1.ActivityA

切换后任务栈:

* Task{4c89ef1 #56 type=standard A=10147:com.chao.studydemoa U=0 visible=true mode=fullscreen translucent=false sz=3}
mActivityComponent=com.chao.studydemoa/.MainActivity
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{88e44b2 u0 com.chao.studydemoa/.MainActivity t56}, ActivityRecord{cbd889a u0 com.chao.studydemoa/.DemoActivityB t56}, ActivityRecord{5bd93b0 u0 com.chao.studydemo/.DemoActivityA t56}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{12dac03 15495:com.chao.studydemoa/u0a147}
* Task{424c9d7 #55 type=standard A=10146:com.chao.studydemo U=0 visible=false mode=fullscreen translucent=true sz=2}
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.chao.studydemo/.MainActivity}
Activities=[ActivityRecord{b0b3e00 u0 com.chao.studydemo/.MainActivity t55}, ActivityRecord{7b88443 u0 com.chao.studydemo/.DemoActivityA t55}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{4ad9639 15457:com.chao.studydemo/u0a146}

(2)接着上面,我们又从App1.ActivityA启动App2.ActivityB

任务栈信息:

* Task{4c89ef1 #56 type=standard A=10147:com.chao.studydemoa U=0 visible=true mode=fullscreen translucent=false sz=4}
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{88e44b2 u0 com.chao.studydemoa/.MainActivity t56}, ActivityRecord{cbd889a u0 com.chao.studydemoa/.DemoActivityB t56}, ActivityRecord{5bd93b0 u0 com.chao.studydemo/.DemoActivityA t56}, ActivityRecord{d0b5acd u0 com.chao.studydemoa/.DemoActivityB t56}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{12dac03 15495:com.chao.studydemoa/u0a147}
* Task{424c9d7 #55 type=standard A=10146:com.chao.studydemo U=0 visible=false mode=fullscreen translucent=true sz=2}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{b0b3e00 u0 com.chao.studydemo/.MainActivity t55}, ActivityRecord{7b88443 u0 com.chao.studydemo/.DemoActivityA t55}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{4ad9639 15457:com.chao.studydemo/u0a146}

这里的到了个结论:

singleTop模式下,Activity会进入启动它的Activity所在的Task栈中,这个结论对于在启动其他App的Activity也成立。

情况三:单一Task&含有SingleTask的模式,App切换的Activity栈情况

启动模式:

ActivityA:SingleTask

ActivityB:SingleTask

App1、App2:MainActivity:standard

TaskAffinity:

都是默认情况下的TaskAffinity(包名)

初始化启动顺序:

Step1:启动App1:MainActivity——>ActivityA ;

Step2:启动App2:MainActivity——>ActivityB;

(1)从ActivityB切换至ActivityA:

切换后任务栈:

* Task{50e029e #59 type=standard A=10146:com.chao.studydemo U=0 visible=true mode=fullscreen translucent=false sz=2}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{42e3cab u0 com.chao.studydemo/.MainActivity t59}, ActivityRecord{3f066e5 u0 com.chao.studydemo/.DemoActivityA t59}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{56e1f08 16015:com.chao.studydemo/u0a146}
* Task{71860d2 #60 type=standard A=10147:com.chao.studydemoa U=0 visible=false mode=fullscreen translucent=true sz=2}
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{55a00a5 u0 com.chao.studydemoa/.MainActivity t60}, ActivityRecord{ad2075c u0 com.chao.studydemoa/.DemoActivityB t60}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{822bc7a 16052:com.chao.studydemoa/u0a147}

(2)将MainActivity启动模式变为:singleTask。这时如果我们从App2.ActivityB切换至App1.MainActivity会发什么?

* Task{544e909 #63 type=standard A=10146:com.chao.studydemo U=0 visible=true mode=fullscreen translucent=false sz=1}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{c28ce6a u0 com.chao.studydemo/.MainActivity t63}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{c405f5b 16353:com.chao.studydemo/u0a146}
* Task{13c8924 #64 type=standard A=10147:com.chao.studydemoa U=0 visible=false mode=fullscreen translucent=true sz=2}
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{4b6348c u0 com.chao.studydemoa/.MainActivity t64}, ActivityRecord{f33e97f u0 com.chao.studydemoa/.DemoActivityB t64}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{5df37d5 16394:com.chao.studydemoa/u0a147}

情况四:多Task&SingleTask模式,App切换时Activity栈的情况

启动模式&TaskAffinity:

App1、App2的MainActivity的LaunchModel = SingleTask, TaskAffinity = 包名;

App1中ActivityA: LaunchModel = SingleTask, TaskAffinity = com.Task;

App2中ActivityB: LaunchModel = SingleTask, TaskAffinity = com.TaskA;

初始化启动顺序:

Step1:启动App1:MainActivity——>ActivityA ;

Step2:启动App2:MainActivity——>ActivityB;

栈顶Activity:ActivityB

初始Activity栈:

App1.MainActivity——>App1.ActivityA——>App2.MainActivity——>App2.ActivityB

//我们可以看到,每一个Activity都在一个Task中,按照他们启动的顺序从上倒下。
* Task{1bf0eaf #72 type=standard A=10147:com.taskA U=0 visible=true mode=fullscreen translucent=false sz=1}
affinity=10147:com.taskA
Activities=[ActivityRecord{24b842 u0 com.chao.studydemoa/.DemoActivityB t72}]
mRootProcess=ProcessRecord{af4c8c9 17097:com.chao.studydemoa/u0a147}
* Task{e17c801 #71 type=standard A=10147:com.chao.studydemoa U=0 visible=false mode=fullscreen translucent=true sz=1}
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{a9c60d0 u0 com.chao.studydemoa/.MainActivity t71}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{af4c8c9 17097:com.chao.studydemoa/u0a147}
* Task{fb80db0 #70 type=standard A=10146:com.task U=0 visible=false mode=fullscreen translucent=true sz=1}
affinity=10146:com.task
Activities=[ActivityRecord{5b82144 u0 com.chao.studydemo/.DemoActivityA t70}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{9d084a2 17054:com.chao.studydemo/u0a146}
* Task{26205fa #69 type=standard A=10146:com.chao.studydemo U=0 visible=false mode=fullscreen translucent=true sz=1}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{77c5084 u0 com.chao.studydemo/.MainActivity t69}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{9d084a2 17054:com.chao.studydemo/u0a146}

(1)从App2.ActivatyB启动App1.ActivityA

切换任务栈:

* Task{fb80db0 #70 type=standard A=10146:com.task U=0 visible=true mode=fullscreen translucent=false sz=1}
affinity=10146:com.task
Activities=[ActivityRecord{5b82144 u0 com.chao.studydemo/.DemoActivityA t70}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{9d084a2 17054:com.chao.studydemo/u0a146}
* Task{1bf0eaf #72 type=standard A=10147:com.taskA U=0 visible=false mode=fullscreen translucent=true sz=1}
affinity=10147:com.taskA
Activities=[ActivityRecord{24b842 u0 com.chao.studydemoa/.DemoActivityB t72}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{af4c8c9 17097:com.chao.studydemoa/u0a147}
* Task{e17c801 #71 type=standard A=10147:com.chao.studydemoa U=0 visible=false mode=fullscreen translucent=true sz=1}
affinity=10147:com.chao.studydemoa
Activities=[ActivityRecord{a9c60d0 u0 com.chao.studydemoa/.MainActivity t71}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{af4c8c9 17097:com.chao.studydemoa/u0a147}
* Task{26205fa #69 type=standard A=10146:com.chao.studydemo U=0 visible=false mode=fullscreen translucent=true sz=1}
affinity=10146:com.chao.studydemo
Activities=[ActivityRecord{77c5084 u0 com.chao.studydemo/.MainActivity t69}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{9d084a2 17054:com.chao.studydemo/u0a146}

这里我们看到,只有Task#294(App1.ActivityA)移动到了Task#296(App2.ActivityB)之前,App1.MainActivity所在的Task#293,并没有移动。

初始栈: App1.MainActivity——>App1.ActivityA——>App2.MainActivity——>App2.ActivityB

操作后的栈:App1.MainActivity——>App2.MainActivity——>App2.ActivityB——>App1.ActivityA

到了这里,得到了实践的验证:

Android的APP切换,实际上是Activity以Task为单位来进行切换,将被选中的Activity所在的Task移动到Stack任务栈的最前端,然后在Task内部使用LaunchModel规则对Task内部的Activity进行操作。

四、总结

standard,singleTop模式下,Activity会进入启动它的Activity所在的Task栈中,这个结论对于在启动其他App的

Activity也成立。

LaunchModel的启动规则,在跨App之间时启动Activity同样成立。

在APP之间切换时。首先,会将切换的App所在的Task移动到最前面;然后,再使用LaunchModel的

规则对Activity进行出栈入栈的操作。

Android的APP切换,实际上是以Task为单位来进行切换,将被选中的Activity所在的Task移动到

Stack任务栈的最前端,然后在Task内部根据Activity的启动模式,使用LaunchModel规则对Task内部

的Activity进行操作。

你可能感兴趣的:(Android基础知识,前端,ui,java)