学习Activity
生命周期,首先咱们要明白,学习它的目的不只在于要知道有哪些生命周期,而是在于明白各回掉函数调用的时机,以便在合适的时机进行正确的操做,如初始化变量、页面展现、数据操做、资源回收等。平时的工做习惯都是,onCreate(xxx)
初始化,onResume()
注册、拉取数据,onPause()
反注册,onDestroy()
释放资源,这篇文章总结了一些和关键生命周期相关联的一些要点。java
Activity
的生命周期理解成为一个金字塔模型,它是基于下面两点:
Activity
所处的状态**这个模型中包含了Activity
的六种状态:bash
Created
:建立完成Started
:可见Resumed
:可见Paused
:部分可见Stopped
:不可见Destroyed
:销毁在这六种状态当中,只有Resumed
、Paused
、Stopped
这几种状态在用户没有进一步操做时会保持在该状态,而其他的,都会在执行完相应的回调函数后快速跳过。ide
protected void onCreate(Bundle savedInstanceState)
Activity
被建立了。Activity
实体对象当中,全部的东西都是未初始化的,咱们通常须要作的事情包括调用setContentView
方法设置该Activity
的布局,初始化类成员变量。onCreate(xxx)
方法执行完以后,Activity
就进入了Created
状态,然而它并不会在这个状态停留,系统会接着回调onStart()
方法由Created
状态进入到Started
状态。onCreate(xxxx)
是全部这些回调方法中惟一有参的,该参数保存了上次因为Activity
被动回收时所保存的数据。protected void onStart()
onStart()
方法执行完后,Activity
就进入了Started
状态,它也一样不会在该状态停留,而是接着回调 onResume()
方法进入Resumed
状态。onStart()
被回调的状况有两种:Created
状态过来Stopped
状态过来,从这种状态过来还会先通过onRestart()
方法。Stopped
状态跳转过来,所以若是咱们在onStop()
当中反注册了一些广播,或者释放了一些资源,那么在这里须要从新注册或者初始化,能够认为,onStart()
和onStop()
是成对的关系。Created
和Started
都不是持久性的状态,那么为何要提供一个onStart()
回调给开发者呢,直接由Created
状态或者是 Stopped
状态通过onResume()
这条路走到Resumed
状态不就能够吗,那么咱们就要分析一下从 onCreate()
到onStart()
,再到onResume()
的过程当中,作了哪些其它的操做,这有利于咱们在平时的开发中区分这两个回调的使用场景,咱们来看一下源码。首先咱们看一下onStart()
方法调用的地方,经过下面这段代码,咱们能够知道Activity
的onStart()
最初是经过Activity#performStart()
方法调用过来的:函数
<!-- Activity.java -->
private Instrumentaion mInstrumentation;
final void performStart() {
mInstrumentation.callActivityOnStart(this);
}
<!-- Instrumentaion.java -->
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
复制代码
而Activity#performStart()
方法是由ActivityThread#performLaunchActivity(
调过来的:布局
<!-- ActivityThread.java -->
private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity a = performLaunchActivity(r, customIntent); //performCreate, performStart()
if (a != null) {
....
handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); //performResume()
....
}
}
//首先看一下调用performCreate, performStart的地方。
private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
mInstrumentation.callActivityOnCreate(activity, r.state); //performCreate
....
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); //1.onRestoreIntanceState()
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
mInstrumentation.callActivityOnPostCreate(activity, r.state); //2.onPostCreate
if (!activity.mCalled) {
throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPostCreate()");
}
}
...
}
//这是performResume的入口。
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
ActivityClientRecord r = performResumeActivity(token, clearHide);
}
//最后看一下performResume真正执行的地方。
public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide) {
try {
if (r.pendingIntents != null) {
deliverNewIntents(r, r.pendingIntents); //3.onNewIntent()
r.pendingIntents = null;
}
if (r.pendingResults != null) {
deliverResults(r, r.pendingResults); //4.onActivityResult()
r.pendingResults = null;
}
r.activity.performResume();
}
复制代码
onStart()
到onResume()
的过程当中,还可能会回调onRestoreInstanceState/onPostCreate/onNewIntent/onActvitiyResult
这几个方法。onNewIntent
),或者经过startActivityForResult
方法启动另外一个 Activity
获得结果返回(onActivityResult
)的时候,在onStart()
方法当中获得的并非这两个回调的最新结果,由于上面的这两个方法并无调用,而在onResume()
当中,这点是能够获得保证的。protected void onResume()
Activity
已经彻底可见了,但这个彻底可见的概念并不等同于Activity
所属的Window
被Attach
了,由于在Activity
初次启动的时候,Attach
的操做是在回调onResume()
以后的,也就是下面的这段代码final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
....
ActivityClientRecord r = performResumeActivity(token, clearHide);
....
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
WindowManager.LayoutParams l = r.window.getAttributes();
...
wm.addView(decor, l);
}
}
复制代码
onResume()
方法被回调时,因为DecorView
并不必定Attach
了,所以这时候咱们获取布局内某些View
的宽高获得的值有多是不正确的,既然onResume()
当中不能保证,那么onStart()
方法也是同理,全部须要在attachToWindow
以后才能执行或是指望获得正确结果的操做都须要注意这一点。onResume
当中,咱们通常会作这么一些事:在可见时从新拉取一些须要及时刷新的数据、注册 ContentProvider
的监听,最重要的是在onPause()
中的一些释放操做要在这里面恢复回来。protected void onPause()
Activity
部分不可见,例如一个半透明的界面覆盖在了上面,这时候只要Activity
仍然有一部分可见,那么它会一直保持在Paused
状态。Paused
状态回到Resumed
状态,只会回调onResume
方法。onPause()
方法中,应该暂停正在进行的页面操做,例如正在播放的视频,或者释放相机这些多媒体资源。onPause()
当中,能够保存一些必要数据到持久化的存储,例如正在编写的信息草稿。onPause()
方法,因此若是进行了耗时的操做,那么会影响到新界面的启动时间,官方文档的建议是这些操做应该放到 onStop()
当中去作,其实在onStop()
中也不该当作耗时的操做,由于它也是在主线程当中的,而在主线程中永远不该该进行耗时的操做。GPS
)、以及一些仅当页面得到焦点时才须要的资源。Paused
状态时,Activity
的实例是被保存在内存中的,所以在其从新回到Resumed
状态的过程当中,不须要从新初始化任何的组件。protected void onStop()
Activity
已经彻底不可见了。onPause()
,以后再回调onStop()
。onStop()
执行完以后,系统有可能会销毁这个Activity
实例,在某些极端状况下,有可能不会回调onDestroy()
方法,所以,咱们须要在onStop()
当中释放掉一些资源来避免内存泄漏,而 onDestory()
中须要释放的是和Activity
相关的资源,如线程之类的(这点平时在工做中不多用,通常咱们都是在onDestroy()
中释放全部资源,并且也没有去实现onStart()
方法,究竟何时不会走onDestroy()
,这点值得研究,目前的猜想是该Activity
在别的地方被引用了,致使其不能回收)。Activity
从Stopped
状态回到前台时,会先回调onRestart()
方法,然而咱们更多的是使用onStart()
方法做为onStop()
的对应关系,由于不管是从Stopped
状态,仍是从Created
状态跳转到Resumed
状态,都是须要初始化必要的资源的,而它们通过的共同路径是onStart()
。protected void onDestroy()
Activity
是真正要被销毁了,