• 【Android进阶】Activity和Fragement中onSaveInstanceState()的使用详解


    在activity(或者是fragement)被杀掉之前调用保存每个实例的状态,以保证该状态可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。这个方法在一个activity被杀死前调用,当该activity在将来某个时刻回来时,可以恢复其先前状态。例如,如果activity B启用后位于activity A的前端,在某个时刻activity A因为系统回收资源的问题要被杀掉,A通过onSaveInstanceState将有机会保存其用户界面状态,使得将来用户返回到activity A时能通过onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢复界面的状态。


    不要将这个方法和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)的。


      默认的实现负责了大部分UI实例状态的保存,采用的方式是调用UI层上每个拥有id的view的onSaveInstanceState() ,并且保存当前获得焦点的view的id(所有保存的状态信息都会在默认的onRestoreInstanceState(Bundle)实现中恢复。如果你覆写这个方法来保存额外的没有被各个view保存的信息,你可能想要在默认实现过程中调用或者自己保存每个视图的所有状态。如果被调用,这个方法会在onStop()前被触发,但系统并不保证是否在onPause()之前或者之后触发。


    以上是API文档中的解释,我们在项目中一般在onSaveInstanceState()方法中保存数据,然后再onCreate()或者是onRestoreInstanceState(Bundle)中对界面进行恢复。

    一个项目中的使用情景是,在onSaveInstanceState()中记录当前的可见的第一条listview的item的position信息,然后在onRestoreInstanceState(Bundle)中对listview调用setSelection()方法对位置进行定位,这样对用户体验更加友好

    代码如下:

    @Override
    	public void onSaveInstanceState(Bundle outState) {
    		super.onSaveInstanceState(outState);
    		//这是用SharedPreference实现的一个类,用于对目前的数据进行存储,在调用之前,先把里面的数据清空
    		stateSaver.remove(this.toString());
    		// 记录可见的第一条记录
    		int firstVisiblePosition = listview.getFirstVisiblePosition();
    		if (mInfoAdapter.getList().size() > 0) {
    			//将现在的数据存储在SharedPreference中,便于恢复
    			stateSaver.put(this.toString(), mInfoAdapter.getList());
    			//将位置信息保存在Bundle对象中
    			outState.putInt("firstVisiblePosition", firstVisiblePosition);
    		}
    	}

    在onViewStateRestored()方法中进行数据的恢复

    @Override
    	public void onViewStateRestored(Bundle savedInstanceState) {
    		super.onViewStateRestored(savedInstanceState);
    		//初始化显示位置
    		int firstVisiblePosition = 0;
    		//获得保存的位置信息
    		if (savedInstanceState != null) {
    			firstVisiblePosition = savedInstanceState.getInt("firstVisiblePosition");
    		}
    		if (stateSaver.get(this.toString()) != null) {
    			List<EngineeringInfo> list = stateSaver.get(this.toString());
    			if (list.size() > 0) {
    				mInfoAdapter.setList(list);
    				//恢复到上次看到的位置
    				listview.setSelection(firstVisiblePosition);
    			}
    		}
    	}

    如有疑问,请留言



  • 相关阅读:
    Diagnostic Viewer 显示空白
    ROS 的一些常用命令行功能
    ROS学习(更新中~)
    ubuntu坑(持续更新~)
    PHP延迟静态绑定:static关键字
    php实战正则表达式:验证手机号
    mysql 查询日志
    索引对更新语句速度影响很大
    给table设置滚动条
    PHP 对字符串进行十六进制替换 invalid character in attribute value
  • 原文地址:https://www.cnblogs.com/oversea201405/p/3749562.html
Copyright © 2020-2023  润新知