Activity的保存和恢复需要用到两个方法:
onSaveInstanceState(Bundle outState)
onRestoreInstanceState(Bundle savedInstanceState)
以下简称onSave和onRestore方法。
Activity有其固定的生命周期,从创建到销毁,当Activity因为一些原因,导致有可能会被系统销毁时,系统会调用onSave方法,而如果真的销毁了,而后因为一些原因,该Activity又被恢复重建时,系统会调用该Activity的onRestore方法,用以保存和恢复一些简单的数据,通常是Activity的状态,如一些flag,记录用户操作的一些变量等。一些UI组件的状态也会被保存和恢复,但这是系统行为。
注意,系统保存UI组件状态需要两个条件,1:该组件有id,2该组件获得了焦点。
这里就有需要注意的地方了。onSave和onRestore并不是成对出现,如上所说,只有当该Activity被销毁并重建时,onRestore才会被调用。记住,必须是销毁&重建。而onSave是可能销毁或者肯定销毁但肯定也会重建的情况下被调用。注意,如果是肯定销毁但不重建,则onSave不会被调用。
以下列举一些个人知道的场景,可以帮助理解上面那段话。
可能销毁的情况:1、按下HOME键。 2、从最近应用中选择运行其他的程序。 3、关闭屏幕显示。 4、从当前activity启动一个新的activity。
肯定销毁而后肯定重建的情况:1.屏幕方向切换(没有为该Activity配置configChanges=orientation|screenSize)
肯定销毁但不重建的情况:1、该Activity被返回 2、该Activity所在应用被杀死
重建的情况:上面列举的4中可能销毁的操作,为什么可能会被销毁了呢,那是因为这几种操作都会使Activity进入后台(onStop被执行),当系统内存不足时,就会尝试杀掉这些后台应用以腾出内存空间。杀掉后如果用户通过一些方式又需要该Activity返回前台时,便会重建,如从其他Activity返回,从手机主界面再点开该Activity所在应用,再次点亮屏幕。
如果只配置了configChanges=orientation,Android的规范是屏幕的旋转也会导致screenSize发生改变,且模拟器的表现也是这样的。但在个人的真机下则不会,估计是三方ROM的问题,这里还是要按照推荐的来,如果要配置orientation,则把screenSize一并配上较为稳妥
onSave和onRestore的调用具体发生在Activity生命周期的什么时候呢,网上有的说法是onSave在onPause()前后,onRestore在onStart()前后,前的情况没测试出来,估计是不同机型或者场景下表现各异吧。可以确定的是onSave肯定会在onStop之前就调用到,onRestore肯定会在onResume之前调动到。
另外,在重建的Activity生命周期中,onCreate()方法也可以用来执行恢复操作 onCreate(Bundle savedInstanceState)中的savedInstanceState和onRestore中的savedInstanceState是引用的同一个对象,所以也可以根据实际情况,选择在onCreate时就恢复之前保存的数据。
测试中还了解到,onSave中带的outState和重建后的savedInstanceState两者虽不是相同的对象(equals和==都为false),但都具有相同的hashCode,因为对哈希码不太了解,所以还暂不清楚为什么会是相同的,以后补了这方面知识后再来回答。