Activity生命周期详解(为什么不能在onPause里执行耗时操作)

来源:互联网 发布:淘宝退货金额改0元吗 编辑:程序博客网 时间:2024/06/06 01:53

尊重原创,如果要转载请与版主联系获得同意后注明出处转载


先来一张官方文档贴图,相信大家都看到过:


从一个activity的打开经历onCreate、onStart、onResume,启动完毕,再经过onPause、onStop、onDestroy结束,又或者通过 onRestart、onStart、onResume,从新唤醒,看似简单的外表下又存在着什么样的玄机呢。新建两个activity,然后让一个activity去打开另一个activity,来分析activity的生命周期之间的联系。接下来上代码分析:


新建一个activity,布局文件就是简单的一个按钮并设置了一个go的点击事件:

<Button    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="go main2"    android:id="@+id/button"    android:layout_centerHorizontal="true"    android:onClick="go"    />
activity内部通过log打印出来各生命周期和点击事件:

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    Log.i("lifecycle","MainActivity------------"+"onCreate");}@Overrideprotected void onStart() {    super.onStart();    Log.i("lifecycle","MainActivity------------"+"onStart");}@Overrideprotected void onResume() {    super.onResume();    Log.i("lifecycle","MainActivity------------"+"onResume");}@Override
protected void onPause() {    super.onPause();    Log.i("lifecycle","MainActivity------------"+"onPause");}
@Overrideprotected void onStop() {    super.onStop();    Log.i("lifecycle","MainActivity------------"+"onStop");}@Overrideprotected void onDestroy() {    super.onDestroy();    Log.i("lifecycle","MainActivity------------"+"onDestroy");}public void go(View view) {    Intent intent = new Intent(this, Main2Activity.class);    startActivity(intent);}

然后创建第二个activity,同样打印各生命周期:

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main2);    Log.i("lifecycle","Main2Activity------------"+"onCreate");}@Overrideprotected void onStart() {    super.onStart();    Log.i("lifecycle","Main2Activity------------"+"onStart");}@Overrideprotected void onResume() {    super.onResume();    Log.i("lifecycle","Main2Activity------------"+"onResume");}@Overrideprotected void onPause() {    super.onPause();    Log.i("lifecycle","Main2Activity------------"+"onPause");}@Overrideprotected void onStop() {    super.onStop();    Log.i("lifecycle","Main2Activity------------"+"onStop");}@Overrideprotected void onDestroy() {    super.onDestroy();    Log.i("lifecycle","Main2Activity------------"+"onDestroy");}
准备工作完毕,运行程序:

 MainActivity------------onCreate
 MainActivity------------onStart
 MainActivity------------onResume

没问题,和我们所了解的东西是一样的,点击按钮打开activity2:

 MainActivity------------onPause
 Main2Activity------------onCreate
 Main2Activity------------onStart
 Main2Activity------------onResume
 MainActivity------------onStop

会发现,第一个activity的onPause执行完之后并没有去执行onStop,而是去执行第二个activity的生命周期流程,当第二个activity生命周期流程执行完或者说是展示出来,第一个activity才会去执行onStop。

点击返回按钮,返回第一个activity:

Main2Activity------------onPause
MainActivity------------onStart
MainActivity------------onResume
Main2Activity------------onStop
Main2Activity------------onDestroy

果然,当activity2执行完onPause之后activity1执行恢复流程,恢复完成之后,activity1才会执行onStop和onDestroy。读者们可以这样去理解,onPause和onResume分别对应的是当前activity是否在前台操作,而onStart和onStop所对应的是是否显示出来,那么为什么不能在onPaus中执行耗时操作呢,我们在第一个activity中的onPause中加入sleep,休息3秒:

@Overrideprotected void onPause() {    super.onPause();    Log.i("lifecycle","MainActivity------------"+"onPause");    try {        Thread.sleep(3000);    } catch (InterruptedException e) {        e.printStackTrace();    }}
从新打开activity2:

会发现activity先是没有任何反应3秒,然后才会打开activity2,可见这一系列activity生命周期就算不是同一个activity,执行操作也是串行的,如果在onPause中执行过多操作,就直接影响界面操作以及流畅度,这样就会变得很不友好,这就是为什么不能在activity的onPause里执行耗时操作的原因。

笔者曾经写过一个程序,有一个需求是在第二个activity里不断操作数据库,然后如果返回或者不在前台了(比如突然来电话了,或者按了home键被清理掉),就必须还原数据库操作,于是笔者就在onstop里还原,第一个activity展示数据会在每次onResume的时候刷新界面,看似顺理成章,但通过刚刚的分析,第二个activity执行onResume的时候,第一个activity还没有执行到onStop,所以就会造成显示的错误。


这里再说一种大家不常遇到的情况:

如果打开的第二个activity是以dialog的形式打开的,那么生命周期又会是什么样子的呢,修改AndroidManifest里的activity2属性:

<activity android:name=".Main2Activity" android:theme="@style/Theme.AppCompat.Dialog"/>
然后从新打开activity2:

MainActivity------------onPause
Main2Activity------------onCreate
Main2Activity------------onStart
Main2Activity------------onResume

会发现第二个activity执行完onResume之后,第一个activity也没有执行onStop,这是因为第一个activity虽然不在前台了,但是还在显示状态,所以就没有执行onStop,这就更加验证了我们最开始的结论:“onPause和onResume分别对应的是当前activity是否在前台操作,而onStart和onStop所对应的是是否显示出来”。我们返回第一个activity:

Main2Activity------------onPause
MainActivity------------onResume
Main2Activity------------onStop
Main2Activity------------onDestroy

同样第一个activity也只是执行了onResume,没有执行onStart。


------------------华丽丽的分割线------------------------------


对于不同的启动模式或Intent Flags或操作行为(如横竖屏切换)等有可能会影响到Activity生命周期,此类问题将放在后续相关文章中进行总结。





0 0
原创粉丝点击