前言:

Activity生命周期是每一个Android开发者接触Android之始就会学习的东西,每个人都会说出点什么,我想任何一个经验老道高级语言开发程序员谈到生命周期这个概念,总有一种接触越多体会越深的感觉。

Android是面向对象设计的,Android是面向对象设计的,Android是面向对象设计的。重要的事情先说三遍。Activity到底是对什么的抽象,我想大家都不敢随随便便自己给一个定义。

正文:

首先先贴一张官方正版的生命周期图:


这个图反映了android在正常情况下activity的生命周期变化。

OK我们先简单的看一下官方对Activity的描述:

An activity is a single, focused thing that the user can do. Almost allactivities interact with the user, so the Activity class takes care of

creating a window for you in which you can place your UI with{@link #setContentView}. While activities are often presented to the user

as full-screen windows, they can also be used in other ways: as floatingwindows (via a theme with {@link android.R.attr#windowIsFloating} set)

or embedded inside of another activity (using {@link ActivityGroup}).

意思呢就是:activity是单一的、用户可以操作的东西,基本上所有的activity都和用户交互,所以activity关心创建一个你可以放置UI的视窗。……

我们可以想象一下activity是对什么的抽象,而且定义的生命周期关键点就是这个东东的某些特殊状态点。

那我们再回顾一下基础知识:

activity生命周期中几个关键点所对应的实际场景

1.onCreate

activity开始被创建

2.onRestart

activity被重新启动

3.onStart

activity被启动

4onResume

activity进入可见、可交互状态

5onPause

activity开始暂停

6onStop

activity即将停止

7onDestroy

activity即将销毁

生命周期的演变在图中表现的很详细,再引用google官方的一个表:

Method

Description

Killable?

Next

onCreate()

Called when the activity is first created. This is where you should do all of your normal static set up: create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state, if there was one.

Always followed by onStart().

No

onStart()

onRestart()

Called after your activity has been stopped, prior to it being started again.

Always followed by onStart()

No

onStart()

onStart()

Called when the activity is becoming visible to the user.

Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.

No

onResume() or

onStop()

onResume()

Called when the activity will start interacting with the user. At this point your activity is at the top of the activity stack, with user input going to it.

Always followed by onPause().

No

onPause()

onPause()

Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.

Followed by either onResume() if the activity returns back to the front, or onStop() if it becomes invisible to the user.

Yes

onResume() or

onStop()

onStop()

Called when the activity is no longer visible to the user, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed.

Followed by either onRestart() if this activity is coming back to interact with the user, or onDestroy() if this activity is going away.

Yes

onRestart() or

onDestroy()

onDestroy()

The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.

Yes

Nothing


表格中用语言描述了生命周期可能的变化,其实还是看图明显。接下来集中写以下几个问题:

  1. 正常情况下各个生命周期转折点做点什么
  2. 一些不合理的做法和不合理的原因
  3. 异常情况下生命周期

正常情况下各个生命周期转折点做点什么

onCreate(Bundle savedInstanceState)

Called when the activity is starting. This is where most initialization should go: calling setContentView(int) toinflate the activity's UI, using findViewById to programmatically interact withwidgets in the UI, calling managedQuery(android.net.Uri, String[], String,String[], String) to retrieve cursors for data being displayed, etc.
You can call finish from within this function, in which case onDestroy() willbe immediately called without any of the rest of the activity lifecycle(onStart, onResume, onPause, etc) executing.

以上是API描述,onCreate中应该做一些初始化的工作,而且是绝大多是的实例化工作,言下之意是这里很适合做实例化工作(应该做),但存在有些特殊的情况(看到这里你是不会知道特殊情况是什么的)。而且这些初始化工作主要和界面有关,很多人要说,此处不要做耗时操作,是的,因为界面还没有可见,耗时操作会托节奏,但这是主要原因吗?可能阻塞主线程的耗时操作都是不应该在主线程中进行,做一些实例化的行为还谈不上耗时,哪怕是反射实现的。


void android.app.Activity.onStart()

Called after onCreate — or after onRestart when the activity had been stopped, but is now again being displayed to the user. It will be followed by onResume.

如果从正常的生命周期来看,总会觉得去实现onStart有点多余,需要注意的是,界面此时还是不可见的。不可交互的。不要去做动画。(不能确定是否是容错机制,在此处开始一个动画没有遇到过crash或者警告,但起码这时候是看不到的嘛,那就尽量不要在此处做不合理的事情)。

void android.app.Activity.onResume()

Called after onRestoreInstanceState,onRestart, or onPause, for your activity to start interacting with the user. This is a good place to begin animations,open exclusive-access devices (such as the camera), etc.

Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged to know for certain that your activity is visible to the user (for example, to resume a game).

一切和用户交互的准备应当在此前完成,例如添加各种监听器,尽量不要拖到这时候再处理。正如API所说,这时候是打开独占设备或者展示动画的好时机。但是注意一件事情:此时可能处于锁屏2333,用onWindowFocusChanged回调来获知用户可以看到这个activity了。

void android.app.Activity.onPause()

Called as part of the activity lifecycle when an activity is going into thebackground, but has not (yet) been killed. The counterpart toonResume.

When activity B is launched in front ofactivity A, this callback will be invoked on A. B will not be created until A'sonPause returns, so be sure to not do anything lengthy here.

This callback is mostly used for savingany persistent state the activity is editing, to present a "edit inplace" model to the user and making sure nothing is lost if there are notenough resources to start the new activity without first killing this one. Thisis also a good place to do things like stop animations and other things thatconsume a noticeable amount of CPU in order to make the switch to the nextactivity as fast as possible, or to close resources that are exclusive accesssuch as the camera.

In situations where the system needs morememory it may kill paused processes to reclaim resources. Because of this, you should be sure that all of your stateis saved by the time you return from this function. In generalonSaveInstanceState is used to save per-instance state in the activity and thismethod is used to store global persistent data (in content providers, files,etc.)

After receiving this call you will usuallyreceive a following call to onStop (after the next activity has been resumed anddisplayed), however in some cases there will be a direct call back to onResumewithout going through the stopped state.

处于后台了,你可以做一些关键数据的保存,免得被内存回收了。


void android.app.Activity.onStop()

Called when you are no longer visible tothe user. You will next receive either onRestart, onDestroy, or nothing,depending on later user activity.

Note that this method may never be called, in low memory situations where the system does not have enough memory to keep your activity's process running after its onPause method is called.

看起来像是一个完成反注册的好时机,但注意可能这个方法不会被回调,内存少的时候activity会有直接被干掉的

protected void onDestroy ()

Perform any final cleanup before anactivity is destroyed. This can happen either because the activity is finishing(someone called finish() on it, or because the system is temporarily destroyingthis instance of the activity to save space. You can distinguish between thesetwo scenarios with the isFinishing() method.

Note: do not count on this method being called as a place for saving data! For example, if an activity is editing data in a content provider, those editsshould be committed in either onPause() or onSaveInstanceState(Bundle), nothere. This method is usually implemented to free resources like threads thatare associated with an activity, so that a destroyed activity does not leavesuch things around while the rest of its application is still running. Thereare situations where the system will simply kill the activity's hosting processwithout calling this method (or any others) in it, so it should not be used todo things that are intended to remain around after the process goes away.

Derived classes must call through to thesuper class's implementation of this method. If they do not, an exception willbe thrown.

一些不合理的做法和不合理的原因


onCreate()中实现所有的初始化

Activity的onCreate()方法被调用时,Activity处于不可见状态,如果做动画等,视图还不存在呢,所以存在问题;

Activity A 切换到 Activity B,再切换到 ActivityA(Single Instance模式,依旧是原来的实例),实例已经存在,onCreate不再被调用,那Activity A从后台切换至前台时,一些有必要的初始化就没法实现,也是存在问题的;

将所有的初始化都在onStart()中实现

onCreate中:

This is where mostinitialization should go: calling setContentView(int) to inflate the activity'sUI, using findViewById to programmatically interact with widgets in the UI,calling managedQuery(android.net.Uri, String[], String, String[], String) toretrieve cursors for data being displayed, etc.

我想这些内容你不应当忽视。

虽然在onStart()中实现findviewbyid也可行,但我认为这没有必要,因为每次调用onStart()都会重新实例化view、控件。

一些特殊的初始化、变量的注册也不应当放在这里

而且onStart, onResume,onCreate都不是真正visible的时间点,真正的visible时间点是onWindowFocusChanged()函数被执行时。这在onResume()中提及

将所有的反注册都在onStop()中实现

onResume() 的注释中,建议在 onResume()中打开独占设备(比如相机),与 onResume() 对应的是 onPause(),所以所有的去初始化操作放在onStop()中执行,并不合适,应当做该做的事情。

而且onStop() 的注释中明确地写了:在内存不足而导致系统无法保留此进程的情况下,onStop() 不会被执行。

这里我们要谈一下activity跳转时两个activity生命周期的变化,这样才能更好地理解这些重载函数应该执行些什么。

Activity间跳转时(从Activity A跳到Activity B):

1.调用Activity AonPause()

2.Activity B的初始化流程(onCreate()--> onStart() --> onResume()),

3.调用Activity AonStop()

onResume() 的注释中,建议是在 onResume() 中打开独占设备(比如相机),与 onResume() 对应的是 onPause() ,关闭相机的操作也应该在此方法中被调用;

考虑一下如下场景:

Activity A打开了相机,此刻跳转到Activity B,Activity B也要打开相机。

若Activity A的onPause() 在 Activity B启动后(准确的说是调用Activity B的onResume()之后)再被调用,那Activity B无法打开相机,因为相机作为独占资源被Activity A占用。

onPause() 的注释中指出:在这个方法中执行停止动画等比较耗CPU的操作。如果不先执行这些操作,就先启动新应用,是不合逻辑的;

从用户体验的角度来分析,最后调用onStop()比较合理,当用户触发某事件切换到新的Activity,用户肯定是想尽快进入新的视图进行操作,而调用onStop()是会耗时的(即使很短)。

底层执行Activity A的onPause()时,有一定的时间限制的,当ActivityManagerService通知应用进程暂停指定的Activity时,如果对应的onPause()在500ms内还没有执行完,ActivityManagerService就会强制关闭这个Activity。如下就是对应的onPause()执行超时常量定义:

// How long we wait until giving up on the last activity to pause.

//This is short because it directly impacts the responsiveness of startingthe

// next activity.

static final int PAUSE_TIMEOUT = 500; // 定义在ActivityStack.java中

这里总结一下,一般我们可以这样做:

onCreate函数:注册你要用到的变量,比如说service,receiver,这些变量是无论你的Activity是在前台还是在后台都能够被响应到的,调用setContentView()函数初始化布局信息。

onStart函数:注册一些变量。这些变量必须在Android Activity类在前台的时候才能够被响应(或者这样说更明确,变量的注册更应当放在onCreate中,但是有些变量的注册必须在activity处于前台时才可行,这些则放在onStart中)。

onResume函数:调用一些刷新UI的函数,每当Activity调用到这里时就要刷新一下UI各控件的状态。

onPause函数:一般是做一些变量的设置,或者保存,因为这个时候Activity马上就要切到后台处理,可能有些变量就要被释放掉或者状态要做些相应的调整。

onStop函数:反注册在onStart函数中注册的变量。

onDestory函数:反注册在onCreate中注册的变量

异常情况下的生命周期,我们应该做哪些额外的事情:

这些异常情况包括: configure变化,内存回收等等。
各位可能一下子就想到了屏幕旋转等情况。具体的生命周期变化就不绘制了,难以很好的描述。这些情况下我们想做的是优化体验,最基本的一件事情就是避免一些数据和状态的丢失。
保存应当实现onSaveInstanceState(Bundle bundle)函数,将要保存的数据保存到Bundle中。
恢复推荐使用onRestoreInstanceState(Bundle bundle)函数,也可以在onCreate中实现,但需要注意非空判断。
和生命周期相关的一个很重要的内容是内存泄漏,限于精力本篇就不扯了










更多相关文章

  1. 第十七章 Android(安卓)常见的Service
  2. Android面试系列文章2018之Android部分之自定义View篇
  3. android 进程之间通信--Android(安卓)使用【AIDL】调用外部服务
  4. Android(安卓)4.0 input touch解析(一)
  5. Android应用程序窗口(Activity)的运行上下文环境(Context)的创建过程
  6. Android(安卓)下使用 JSON 实现 HTTP 请求
  7. android的wifi网卡移植详细过程已经通用驱动的问题
  8. Activity生命周期
  9. 在android 下支持ntfs-3g

随机推荐

  1. android 前后台运行判断(使用场景如:在app
  2. 多个launcher时开机只启动默认的
  3. Android 实现模拟按键方法一
  4. android list view
  5. android textview改变部分文字的颜色
  6. android软件键盘隐藏
  7. Android中Dialog中自定义EditView导致软
  8. Android回到底部和返回顶部实现
  9. 解读Android(安卓)LOG机制的实现
  10. Android 保存联系人,包括部门\职位\传