http://ice-k.iteye.com/blog/1018956
Activity的生命周期里并没有提到onSaveInstanceState的触发,这个函数提供了为我们在某些情况下保存Activity信息的机会,但需要注意的是这个函数不是什么时候都会被调用的,官方文档解释的比较清楚,特此
翻译一下。
原文出处:android-sdk-windows-1.5_r3/docs/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
protected void onSaveInstanceState (Bundle outState)
Called to retrieve per-instance state from an activity before
being killed so that the state can be restored in onCreate(Bundle) or
onRestoreInstanceState(Bundle) (the 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 onCreate(Bundle) or
onRestoreInstanceState(Bundle).
在activity被杀掉之前调用保存每个实例的状态,以保证该状态可以在onCreate(Bundle)或者
onRestoreInstanceState(Bundle)
(传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。这个方法在一个activity被杀死前调用,当该
activity在将来某个时刻回来时可以恢复其先前状态。例如,如果activity B启用后位于activity
A的前端,在某个时刻activity
A因为系统回收资源的问题要被杀掉,A通过onSaveInstanceState将有机会保存其用户界面状态,使得将来用户返回到activity
A时能通过onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢复界面的状态。
Do not confuse this method with activity lifecycle callbacks
such as onPause(), which is always called when an activity is being
placed in the background or on its way to destruction, or onStop() which
is called before destruction. One example of when onPause() and
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
onSaveInstanceState(Bundle) on B because that particular instance will
never be restored, so the system avoids calling it. An example when
onPause() is called and not onSaveInstanceState(Bundle) is when activity
B is launched in front of activity A: the system may avoid calling
onSaveInstanceState(Bundle) 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.
不要将这个方法和activity生命周期回调如onPause()或onStop()搞混淆了,onPause()在activtiy被放置到背景或者
自行销毁时总会被调用,onStop()在activity被销毁时被调用。一个会调用onPause()和onStop(),但不触发
onSaveInstanceState的例子是当用户从activity B返回到activity
A时:没有必要调用B的onSaveInstanceState(Bundle),此时的B实例永远不会被恢复,因此系统会避免调用它。一个调用
onPause()但不调用onSaveInstanceState的例子是当activity B启动并处在activity
A的前端:如果在B的整个生命周期里A的用户界面状态都没有被破坏的话,系统是不会调用activity
A的onSaveInstanceState(Bundle)的。
The default implementation takes care of most of the UI
per-instance state for you by calling 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
onRestoreInstanceState(Bundle)). 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 onStop(). There are no guarantees about
whether it will occur before or after onPause().
默认的实现负责了大部分UI实例状态(的保存),采用的方式是调用UI层上每个拥有id的view的onSaveInstanceState()
,并且保存当前获得焦点的view的id(所有保存的状态信息都会在默认的onRestoreInstanceState(Bundle)实现中恢复)。
如果你覆写这个方法来保存额外的没有被各个view保存的信息,你可能想要在默认实现过程中调用或者自己保存每个视图的所有状态。如果被调用,这个方法会
在onStop()前被触发,但系统并不保证是否在onPause()之前或者之后触发。
很多不明白Activity类中包含的onSaveInstanceState和onRestoreInstanceState有什么用,首先声
明下使用这两个方法时一定要注意情况和了解Activity的生命周期,否则有的时候
onSaveInstanceState和onRestoreInstanceState
可能不会被触发,虽然他们都是Activity的重写方法。(文/Android开发网)
他们比较常用到的地方是
Sensor、Land和Port布局的自动切换,过去Android开发网曾经说过解决横屏和竖屏切换带来的数据被置空或者说onCreate被重复调
用问题,其实Android提供的onSaveInstanceState方法可以保存当前的窗口状态在即将布局切换前或当前Activity被推入历史
栈,其实布局切换也调用过onPause所以被推入Activity的history
stack,如果我们的Activity在后台没有因为运行内存吃紧被清理,则切换回时会触发onRestoreInstanceState方法。
这两个方法中参数均为Bundle,可以存放类似 SharedPreferences 的数据,所以使用它们作为当前窗口的状态保存是比较合适的。实际使用代码
@Override
protected void onSaveInstanceState(Bundle outState){
outState.putString("lastPath", "/sdcard/android123/cwj/test");
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String cwjString = savedInstanceState.getString("lastPath");
}
onSaveInstanceState和onRestoreInstanceState触发的时机
已有 199 次阅读 2011-3-10 10:32 |个人分类:Android|关键词:onSaveInstanceState onRestoreInstanceState
先看Application Fundamentals上的一段话:
Android calls onSaveInstanceState() before the activity becomes
vulnerable to being destroyed by the system, but does not bother calling
it when the instance is actually being destroyed by a user action (such
as pressing the BACK key)
从这句话可以知道,当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。
注意上面的双引号,何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。这种可能性有哪些?通过重写一个
activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我
们可以清楚地知道当某个activity(假定为activity
A)显示在当前task的最上层时,其onSaveInstanceState方法会在什么时候被执行,有这么几种情况:
1、当用户按下HOME键时。这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
2、长按HOME键,选择运行其他的程序时。
3、按下电源按键(关闭屏幕显示)时。
4、从activity A中启动一个新的activity时。
5、屏幕方向切换时,例如从竖屏切换到横屏时。在屏幕切换之前,系统会销毁activity A,在屏幕切换之后系统又会自动地创建activity A,所以onSaveInstanceState一定会被执行
总而言之,onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则
onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。
至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和
onRestoreInstanceState方法“不一定”是成对的被调用的,onRestoreInstanceState被调用的前提
是,activity A“确实”被系统销毁了,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用,例如,当正在显示activity
A的时候,用户按下HOME键回到主界面,然后用户紧接着又返回到activity A,这种情况下activity
A一般不会因为内存的原因被系统销毁,故activity A的onRestoreInstanceState方法不会被执行
另外,onRestoreInstanceState的bundle参数也会传递到onCreate方法中,你也可以选择在onCreate方法中做数据还原