-
子类必须在onCreate中调用 super 方法,也就是super.onCreate, 否则会抛出异常。(尽量保证super方法在子类onCreate方法的第一行)
-
如果onCreate方法的参数onSaveInstanceState不为空,那么它是Activity最近被系统杀死时保存了你在onSaveInstanceState方法中设置的值,你可以用它来恢复数据。
其他注意事项是你不能在此方法中执行任何耗时的代码,在所有的Activity的生命周期方法中也是如此。
2. onContentChanged
说明:
onContentChanged方法其实来自于Window的Window.Callback接口中的回调方法,Activity实现了该接口,该方法实际上相当于一个hook方法,每当Window的setContentView方法被调用时它就会被调用。
/**
* This hook is called whenever the content view of the screen changes
* (due to a call to
* {@link Window#setContentView(View, android.view.ViewGroup.LayoutParams)
* Window.setContentView} or
* {@link Window#addContentView(View, android.view.ViewGroup.LayoutParams)
* Window.addContentView}).
*/
在onCreate方法中调用的setContentView方法,实际上是会调用Window的setContentView方法,在Activity的源码当中它的实际调用者是PhoneWindow对象,PhoneWindow是Window抽象类的子类,在PhoneWindow的源码中,setContentView方法调用了onContentChanged方法。
也就是说Activity的内容布局发生变化时,就会回调此方法,因此我们可以选择在此方法中进行view的一些初始化操作,比如findViewById()操作,可以放在此方法中进行。不过此方法在实际开发中并不常用,除非你的布局在Activity创建以后会重新设置,此方法或许有用。
3. onStart
说明:
这个方法会在Activity实例被创建的时候,以及经过onStop之后重新返回该Activity时会被调用。来看源码的注释说明:
/**
* Called after {@link #onCreate} — or after {@link #onRestart} when
* the activity had been stopped, but is now again being displayed to the
* user. It will be followed by {@link #onResume}.
*
* Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown.
*/
没有啥特别的,就是除了onCreate会调用它之外,也会在onRestart方法之后调用它(此时肯定是被其他ac遮挡状态)。 经过onRestart方法之后再调用onStart后,窗口将会对用户可见,这也就告诉我们如果想要用户更快的看到界面,就不要在onCreate和onStart方法中做过多无关UI的操作。另外不要忘记在子类的onStart方法中调用super.onStart方法(并尽量保证在第一行),否则同样会抛异常。
4. onRestoreInstanceState
说明:
这个方法比较有意思,主要是用来恢复数据的,在一般情况下它不会被调用,只有当这个Activity是被系统杀死并且需要再次展现该Activity的时候会被调用。
/**
* This method is called after {@link #onStart} when the activity is
* being re-initialized from a previously saved state, given here in
* savedInstanceState. Most implementations will simply use {@link #onCreate}
* to restore their state, but it is sometimes convenient to do it here
* after all of the initialization has been done or to allow subclasses to
* decide whether to use your default implementation. The default
* implementation of this method performs a restore of any view state that
* had previously been frozen by {@link #onSaveInstanceState}.
*
* This method is called between {@link #onStart} and
* {@link #onPostCreate}.
*
* @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
*
*/
该方法会在onStart方法之后,onPostCreate方法之前被调用,它有一个参数savedInstanceState,这是一个Bundle对象,它是在onSaveInstanceState方法中保存数据的对象参数。
当你需要恢复View的状态时你可以选择在onSaveInstanceState方法中为该参数设置值,这样当Activity被系统销毁重建时就可以在onRestoreInstanceState方法的参数中获得该参数来重新恢复你的布局状态。
值得注意的是,在onCreate方法中也有一个savedInstanceState,它跟onRestoreInstanceState方法里的参数区别是,在onCreate方法中的这个参数是可以为空的(首次创建),而对于onRestoreInstanceState方法,只要它被调用,这个参数就一定不为空。
另外实测发现,该方法确实是 “当且仅当Activity被系统杀死,再由系统恢复” 时,才会被调用的,也就是说假如你主动调用了finish方法去干掉它,或者别人调用了finish方法干掉了它,或者是用户主动干掉了它,或者由于异常挂掉了,都不要指望在它重新创建的时候会走onRestoreInstanceState方法,这时重建Activity的时候都不会调用此方法的。经过我自己的手机上的测试,在发生屏幕旋转的时候Activity重建会调用onRestoreInstanceState方法, 因为这种情况系统也会先杀死Activity然后再重新创建。
5. onPostCreate
说明:
此方法会在onStart和onRestoreInstanceState之后调用,当然如果onRestoreInstanceState没有被调用,那么onStart之后会直接调用它。只有当Activity首次创建的时候才会调用它,当过onStop再次回到Activity时并不会执行它。来看它的源码注释:
/**
* Called when activity start-up is complete (after {@link #onStart}
* and {@link #onRestoreInstanceState} have been called). Applications will
* generally not implement this method; it is intended for system
* classes to do final initialization after application code has run.
*
* Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown.
*
* @param savedInstanceState If the activity is being re-initialized after
* previously being shut down then this Bundle contains the data it most
* recently supplied in {@link #onSaveInstanceState}. Note: Otherwise it is null.
* @see #onCreate
*/
官方注释说这个方法通常没必要重写,设计意图是为了给系统类使用的,实际中此方法看起来也确实没多大卵用,你可以选择性的使用。此方法携带savedInstanceState参数,同样可以做恢复View操作。重写的话子类同样必须要调用super方法。
6. onStateNotSaved
说明:
/**
* Called when an {@link #onResume} is coming up, prior to other pre-resume callbacks
* such as {@link #onNewIntent} and {@link #onActivityResult}. This is primarily intended
* to give the activity a hint that its state is no longer saved – it will generally
* be called after {@link #onSaveInstanceState} and prior to the activity being
* resumed/started again.
*/
这个方法看起来也没有什么卵用,而且它的调用时机不是严格按照顺序确定的,在一开始的完整流程图中,关于这个方法其实是缺少了一种情况的,当Activity第一次创建的时候,它会在onPostCreate之后被调用,而在Activity经过onStop再返回的时候它的顺序又不是这样的,此时会在onRestart方法之前调用它,但是当我手机锁屏再打开之后它又是在onStart之后调用的。
但不管怎样onStateNotSaved都会保证总是在onResume之前,以及在onNewIntent和onActivityResult之前被调用,这可能是该方法唯一有用的点了吧,可以允许你在onResume或onActivityResult之前的某个时机做一些事情。看了下该方法是在API 23 Android 6.0被加入的。
7. onResume
说明:
这个方法应该很常用了,此方法会在onStart方法之后执行,这是唯一确定的执行顺序,如果是首次创建会执行它,当然当Activity经历onPause或onStop之后也会执行到此方法。如果首次创建时有这几个方法onRestoreInstanceState、onPostCreate、onStateNotSaved,那么onStart会在他们之后执行。
/**
* Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or
* {@link #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 {@link #onWindowFocusChanged} to know for certain that your
* activity is visible to the user (for example, to resume a game).
*
* Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown.
*
*/
官方注释说明明确指出,不能以此方法作为判断标志来确定当前activity是都是对用户可见的,因为可能有其他的系统弹窗在该activity前面,比如系统软键盘(我想官方这里的意思可能是不一定完全对用户可见,但是经过onResume之后setContentView设置的内容就会显示出来)。同样,子类必须调用super方法,否则会报异常。(尽量保证super在第一行)
虽然官方建议onResume不能作为用户可见的依赖方法,但实际当中基本上我们会在此方法中恢复一些之前停止的状态,如恢复之前在onPause中停止的动画、视频播放、Camera预览等,因为只要onResume被调用了说明用户之前的activity回到前台(有可能不是完全可见,只有一部分可见,但用户肯定是能看到它的,至少是部分),从体验角度来讲是需要这样处理的。
此外,不能在onResume方法中做额外的耗时任务,如数据保存数据库,I/O读写等,这将导致Activity的卡顿,或者用户重新回来的时候卡顿,影响交互体验。
8. onPostResume
说明:
此方法跟onPostCreate方法类似,会紧跟在onResume方法之后被调用。
/**
* Called when activity resume is complete (after {@link #onResume} has
* been called). Applications will generally not implement this method;
* it is intended for system classes to do final setup after application
* resume code has run.
*
* Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown.
*
*/
同样,从官方的注释说明来看它目前并没有什么卵用。。
9. onAttachedToWindow
说明:
该方法是Window中Wind
ow.Callback接口中的方法,该方法会在window被添加的WindowManager上时被调用。从调用顺序上看,它会在onPostResume方法之后被调用,但是只有Activity首次创建才会调用。
/**
* Called when the main window associated with the activity has been
* attached to the window manager.
* See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
* for more information.
* @see View#onAttachedToWindow
*/
官方注释让看View#onAttachedToWindow()方法,但是我看了下View的这个方法中并没有找到调用Window.Callback的onAttachedToWindow方法,于是后来到DectorView类中终于找到了该方法的回调,我们知道DectorView是最顶层的View,当我们设置给PhoneWindow对象的contentView最终都会被加到DectorView上,当然如果你的Activity没有调用setContentView的话,也是会有默认的DectorView对象的。所以,实际上是DectorView被添加到PhoneWindow时会调用此方法。因此onAttachedToWindow在Activity创建后一定被执行的,并且从该方法开始View才真正被绘制在窗口之上,也是我们最终看到的东西。所以严格意义来讲,经过该方法之后Activity才处于可以与用户进行交互的状态。这也是为什么在阿里的android开发手册当中推荐你在onAttachedToWindow方法之后再去创建显示弹窗。
10. onPause
说明:
此方法也是高频使用的方法,通常在Activity不在前台(被其他Activity的页面完全遮挡,或者部分可见)时被调用。
/**
* Called as part of the activity lifecycle when an activity is going into
* the background, but has not (yet) been killed. The counterpart to
* {@link #onResume}.
*
* When activity B is launched in front of activity A, this callback will
* be invoked on A. B will not be created until A’s {@link #onPause} returns,
* so be sure to not do anything lengthy here.
*
* This callback is mostly used for saving any persistent state the
* activity is editing, to present a “edit in place” model to the user and
* making sure nothing is lost if there are not enough resources to start
* the new activity without first killing this one. This is also a good
* place to do things like stop animations and other things that consume a
* noticeable amount of CPU in order to make the switch to the next activity
* as fast as possible, or to close resources that are exclusive access
* such as the camera.
*
* In situations where the system needs more memory it may kill paused
* processes to reclaim resources. Because of this, you should be sure
* that all of your state is saved by the time you return from
* this function. In general {@link #onSaveInstanceState} is used to save
* per-instance state in the activity and this method is used to store
* global persistent data (in content providers, files, etc.)
*
* After receiving this call you will usually receive a following call
* to {@link #onStop} (after the next activity has been resumed and
* displayed), however in some cases there will be a direct call back to
* {@link #onResume} without going through the stopped state.
*
* _Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown._
*/
官方注释说明中提到,当另一个Activity B需要被创建来到Activity A的前台时,只有当Activity A的onPause方法执行完毕后,才会执行Activity B的创建生命周期方法。所以不应该在该方法中做任何耗时任务。点击查看:Activity启动另一个Activity并返回的完整生命周期
onPause方法被调用时,我们应该释放或者停止任何消耗CPU资源的行为,以便下一个Activity能得到快速的切换显示,比如结束或者暂停正在执行的动画、正在播放的视频、Camera预览、正在使用的系统服务(如GPS或其他传感器)等等。如有必要,需要在onPause方法中对任何用户正在编辑的信息进行持久化的保存,以便用户再次回来时能恢复之前的状态。
对系统而言,如果你的应用不是在前台,也就是经过onPause之后的(当然是onPause之后的那个Activity不属于你的应用的情况),会变成一个后台进程,而后台进程在内存不足时会被系统杀死。因此onPause方法是我们保存全局持久化数据的一个重要方法。虽然在onResume之后会调用onSaveInstanceState方法,在onSaveInstanceState方法中也可以来保存数据,但是该方法的时机较晚,主要用来保存一些UI状态的数据。
注意,当调用finish方法或被系统杀死的时候,onPause是不会被调用的。另外子类一定要调用super方法,否则会报异常。(并尽量保证在第一行)还有就是如果被自己Activity show出来的弹窗遮挡部分的话,onPause也是不会被调用的,必须是被其他Activity show出来的弹窗才能满足条件。
11. onSaveInstanceState
说明:
此方法会在Activity被销毁时调用,可以在该方法中进行UI状态的保存,并在onCreate或者onRestoreInstanceState方法中进行恢复。
/**
* Called to retrieve per-instance state from an activity before being killed
* so that the state can be restored in {@link #onCreate} or
* {@link #onRestoreInstanceState} (the {@link Bundle} populated by this method
* will be passed to both).
*
* This method is called before an activity may be killed so that when it
* comes back some time in the future it can restore its state. For example,
* if activity B is launched in front of activity A, and at some point activity
* A is killed to reclaim resources, activity A will have a chance to save the
* current state of its user interface via this method so that when the user
* returns to activity A, the state of the user interface can be restored
* via {@link #onCreate} or {@link #onRestoreInstanceState}.
*
* Do not confuse this method with activity lifecycle callbacks such as
* {@link #onPause}, which is always called when an activity is being placed
* in the background or on its way to destruction, or {@link #onStop} which
* is called before destruction. One example of when {@link #onPause} and
* {@link #onStop} is called and not this method is when a user navigates back
* from activity B to activity A: there is no need to call {@link #onSaveInstanceState}
* on B because that particular instance will never be restored, so the
* system avoids calling it. An example when {@link #onPause} is called and
* not {@link #onSaveInstanceState} is when activity B is launched in front of activity A:
* the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn’t
* killed during the lifetime of B since the state of the user interface of
* A will stay intact.
*
* The default implementation takes care of most of the UI per-instance
* state for you by calling {@link android.view.View#onSaveInstanceState()} on each
* view in the hierarchy that has an id, and by saving the id of the currently
* focused view (all of which is restored by the default implementation of
* {@link #onRestoreInstanceState}). If you override this method to save additional
* information not captured by each individual view, you will likely want to
* call through to the default implementation, otherwise be prepared to save
* all of the state of each view yourself.
*
* If called, this method will occur before {@link #onStop}. There are
* no guarantees about whether it will occur before or after {@link #onPause}.
*
* @param outState Bundle in which to place your saved state.
*
*/
一般情况下它会在onPause方法之后被调用,但是不能指望一定是在onPause方法之后被调用,最简单的情况比如打开一个Activity,然后按back键关闭它,这时系统就不会调用该方法,或者直接调用finish方法也不会调用该方法。当系统内存不足时可能会直接调用该方法,而不会调用其他任何生命周期方法。总之该方法跟生命周期的依赖不是固定的。
目前能确定调用该方法的场景有:按下home键、锁屏、跳转到其他Activity、横竖屏切换。能确定的一点是只要该方法被调用到,那么一定是在onStop之前,跟onPause方法的先后顺序不确定。
实际上即便你不实现该方法,该方法的父类默认实现页会将视图树中拥有id的每个控件的UI状态以及获得视图焦点的id进行保存,并在onRestoreInstanceState方法中来为你恢复每个实例的UI状态。但是如果你有额外的被UI控件持有的信息需要保存,你可能需要重写此方法。
此外,我们应该只在该方法中进行view状态的保存,而不应该依赖该方法做额外的持久化数据保存如数据库保存,上传服务器等等。
12. onStop
说明:
此方法当Activity对用户不可见时被调用,可以在该方法中进行数据持久化保存。
/**
* Called when you are no longer visible to the user. You will next
* receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
* depending on later user activity.
*
* _Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown._
*
*/
类似onPause方法,此方法中也可以进行资源的释放,因为经过onStop之后该Activity也不在前台了,有可能是按了Home键或者其他Activity来到了前台。假如是按了Home键或其他app来到前台,那么该Activity所处进程变成后台进程有可能被系统杀死,所以需要释放那些系统共享资源如GPS、Camera,或者暂停动画、视频播放等销毁CPU的资源。同时时我们可以在onPause方法保存用户数据,以做现场恢复用。
在onStop方法之后,要么是经历onDestroy方法销毁Avtivity,要么是会在稍后重新返回Activity执行onRestart方法。
在子类中必须调用super方法,否则会抛出异常。(尽量保证在第一行)
13. onRestart
说明:
此方法是当前Activity被其他Activity完全遮挡再返回时调用,也就是经过onStop之后,此方法之后会紧接着调用onStart方法。
/**
* Called after {@link #onStop} when the current activity is being
* re-displayed to the user (the user has navigated back to it). It will
* be followed by {@link #onStart} and then {@link #onResume}.
*
* For activities that are using raw {@link Cursor} objects (instead of
* creating them through
* {@link #managedQuery(android.net.Uri , String[], String, String[], String)},
* this is usually the place
* where the cursor should be requeried (because you had deactivated it in
* {@link #onStop}.
*
* _Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown._
*
*/
官方注释提到如果你使用原生的Cursor对象(而不是通过managedQuery方法),可以在该方法中恢复Cursor请求(因为有可能你在onStop中停止了)Cursor请求。但是我看官方的Cursor#requery()
和Cursor#deactivate()
方法都已经弃用,该方法会导致UI线程的ANR。
同样,如果子类想要覆写此方法的话,要调用super方法,否则抛异常。(并尽量放在第一行)
14. onDestroy
说明:
此方法是Activity被销毁的时候调用,一般是调用了finish方法, 也有可能是系统销毁。
/**
* Perform any final cleanup before an activity is destroyed. This can
* happen either because the activity is finishing (someone called
* {@link #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 {@link #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 edits should be committed in either {@link #onPause} or
* {@link #onSaveInstanceState}, not here._ This method is usually implemented to
* free resources like threads that are associated with an activity, so
* that a destroyed activity does not leave such things around while the
* rest of its application is still running. There are situations where
* the system will simply kill the activity’s hosting process without
* calling this method (or any others) in it, so it should not be used to
* do things that are intended to remain around after the process goes
* away.
*
* _Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown._
*
*/
ly implemented to
* free resources like threads that are associated with an activity, so
* that a destroyed activity does not leave such things around while the
* rest of its application is still running. There are situations where
* the system will simply kill the activity’s hosting process without
* calling this method (or any others) in it, so it should not be used to
* do things that are intended to remain around after the process goes
* away.
*
* _Derived classes must call through to the super class’s
* implementation of this method. If they do not, an exception will be
* thrown._
*
*/