问题
对于启动另外一个 Activity 并结束当前 Activity 这一需求,我们常见的做法是在 startActivity(intent)
的同时调用当前 Activity 的 finish()
方法。两个方法“同时”调用也会有先后顺序,调用顺序有影响吗?
写法一:
finish();
startActivity(intent);
写法二:
startActivity(intent);
finish();
回答
经过探究,我的回答是:
1.如果两个方法调用之间没有其他代码,它们的顺序没有影响;
2.如果两个方法之间有其它代码,尤其是耗时任务,应该采用写法二。
解释
接下来,我会对这个回答进行解释,在开始前,需要看一看单独调用两个方法时,相关的 Activity 的生命周期方法的调用顺序。
startActivity(intent)
场景:启动 ActivityA,然后在 ActivityA 中启动 ActivityB,此时 ActivityA 位于栈底,ActivityB 位于栈顶,在启动 ActivityB 的过程中,两个 Activity 的生命周期方法的调用顺序是怎样的呢?
ActivityA 启动 ActivityB.png用 a 代表 ActivityA 的实例,用 b 代表 ActivityB 的实例(下同),调用顺序如下:
a.onPause();
b.onCreate();
b.onStart();
b.onResume();
a.onStop();
finish()
场景:启动 ActivityA,然后在 ActivityA 中启动 ActivityB,接着 ActivityB 调用 finish()
方法,此时 ActivityB 出栈,剩下 ActivityA。
调用 finish()
方法时,两个 Activity 的生命周期方法的调用顺序如下:
b.onPause();
a.onRestart();
a.onStart();
a.onResume();
b.onStop();
b.onDestroy();
有了以上知识准备,就可以开始解释回答了。
两个方法调用之间没有其他代码,顺序不影响
场景:Activity 启动顺序: A => B
ActivityA 启动 ActivityB 并结束自己当 ActivityA 启动 ActivityB 时,先 finish()
后 startActivity(intent)
和先startActivity(intent)
后 finish()
的生命周期方法调用顺序都是:
a.onPause();
b.onCreate();
b.onStart();
b.onResume();
a.onStop();
a.onDestroy();
两个方法调用之间有其它代码,顺序可能有影响
两个方法调用之间有其他代码,我将它表示为:
写法一:
finish();
executeTask();
startActivity(intent);
和写法二:
startActivity(intent);
executeTask();
finish();
场景:Activity 启动顺序: A => B => C,考虑 ActivityB 启动 ActivityC 时的情况
先 startActiviy(intent) 后 finish()
生命周期方法的调用顺序和两个方法之间没有其他代码的的顺序相同,为:
b.onPause();
c.onCreate();
c.onStart();
c.onResume();
b.onStop();
b.onDestroy();
先 finish() 后 startActivity(intent)
生命周期方法的调用顺序随executeTask()
的耗时而变。
将临界值表示为 t 毫秒,则当耗时小于 t 时,调用顺序和上述三种情况相同;当耗时大于 t 时,调用顺序为:
b.onPause();
a.onRestart();
a.onStart();
a.onResume();
a.onPause();
c.onCreate();
c.onStart();
c.onResume();
a.onStop();
b.onStop();
b.onDestroy();
在的我的测试中,临界值 t 的取值范围在 400 到 500 毫秒之间。值得一提的是,当executeTask()
的耗时略大于 t 时,并感觉不到还悄悄切换了 ActivityA,不过这也并不能充当这是一种好的写法的充分理由,毕竟切换 ActivityA 的开销还是付出了。
因此,在两个方法调用中间有其他代码时,应该采用写法二:先 startActivity(intent)
后 finish()
。
总结
经过以上分析,我们可以得出的结论是:
当启动另外一个 Activity 并结束当前 Activity 时,
- 应该优先采用
startActivity()
和finish()
两个方法之间没有其他代码的写法:
[executeTask();]
finish();
startActivity(intent);
[executeTask();]
或者
[executeTask();]
startActivity(intent);
finish();
[executeTask();]
注:至于 executeTask()
在前和在后的优劣,我也没有深入探究。
- 如果确实需要在两者之间添加其他代码,则先
startActivity(intent)
后finish()
:
startActivity(intent);
executeTask();
finish();
附:
测试设备参数
- 操作系统:MIUI 12.0.4 稳定版 (Android 10)
- 处理器:高通骁龙 765G
- 运行内存:8G
参考资料
- [讨论]启动新界面和结束当前界面,调用finish startActivity的顺序有关系吗?https://github.com/android-cn/android-discuss/issues/618
- 任玉刚.Android 开发艺术探索[M].电子工业出版社:北京,2015:1-8.
网友评论