最新的文档地址http://blog.csdn.net/qq_25412055/article/details/78805525
我们开发app的时候,都会遇到一个问题,当我们的app长时间切到后台,或者一些不在栈顶的页面,当我们重新进入的时候,这个Activity或者Fragment就会被重新onCreate,但是此时,页面中具有id的控件,这些值都是会被系统自动保存下来的。这是因为onSaveInstanceState()这个方法起了作用。
onSaveInstanceState
onSaveInstanceState方法会在什么时候被执行,有这么几种情况:
1、当用户按下HOME键时。
这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
2、长按HOME键,选择运行其他的程序时。
3、按下电源按键(关闭屏幕显示)时。
4、从activity A中启动一个新的activity时。
5、屏幕方向切换时,例如从竖屏切换到横屏时。
当这个页面销毁时,onCreate方法参数中的bundle就不会为null,因此我们通常的onSaveInstanceState的使用方法是:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); if(savedInstanceState != null){ a = savedInstanceState.getInt("A"); } } @Override protected void onSaveInstanceState(Bundle outState) { outState.putInt("A",a); super.onSaveInstanceState(outState); }
在页面可能销毁时,去保存数据,如果页面被销毁了,onCreate中的bundle就不会为null,然后加之判断,从中恢复数据。
AutoSave
但是,如果我们需要保存的参数很多怎么办,如果去一个个的手写,会造成很多重复的工作,且在修改的时候容易出错。如果有一个类似BufferKnife一样的框架,通过一个注解就能去标记我们需要保存的变量,那岂不是更好。
因此,我写了一个简单的框架,通过一个注解可以去自动绑定和恢复要求自动恢复的变量。
使用方法:
配置:
在project的gradle中添加:
dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 。。。。。。。 }
在app的gradle中添加:
apply plugin: 'android-apt'
repositories { maven { url 'https://dl.bintray.com/xqandroid/maven/' } } dependencies { compile 'com.xiaoqi:xqauto-api:1.1.0' apt 'com.xiaoqi:xqauto-processor:1.1.0' compile 'com.xiaoqi:xqauto-savehelper:1.1.0' }
然后编译即可。
使用:
1.在需要保存的Activity或者Fragment的onSaveInstanceState()方法中,添加SaveHelper.save()方法,注意,要在super.onSaveInstanceState()之前添加;
2.在onCreate方法中,需要恢复数据的地方,添加SaveHelper.bind()方法
3.给需要保存状态的变量,添加@NeedSave 注解(注意:变量必须是public ,如果是parcelable的对象,必须加入参数
@NeedSave( isParcelable = true),即可)
如下:
public class MainActivity extends AppCompatActivity { @NeedSave public String test; @NeedSave private boolean b; @NeedSave public Boolean c; @NeedSave public ArrayList<String> t; @NeedSave public Integer i; @NeedSave(isParcelable = true) public Example example; @NeedSave public Float f1; @NeedSave public float f2; @NeedSave public char achar; @NeedSave public char achars[]; @NeedSave public int sssss[]; @NeedSave public int[] sasa; @NeedSave public Bundle bundle; @NeedSave public int a; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); SaveHelper.bind(this,savedInstanceState); } @Override protected void onSaveInstanceState(Bundle outState) { SaveHelper.save(this,outState); super.onSaveInstanceState(outState); } }
添加了这些之后,编译运行app的时候会自动生成一下文件,并且会去自动调用。而不是通过反射,这样效率会更高:
public class MainActivity_SaveStateHelper implements ISaveInstanceStateHelper<MainActivity> { @Override public void save(Bundle outState, MainActivity save) { outState.putInt("A",save.a); outState.putString("TEST",save.test); outState.putBoolean("C",save.c); outState.putSerializable("T",save.t); outState.putInt("I",save.i); outState.putParcelable("EXAMPLE",save.example); outState.putFloat("F1",save.f1); outState.putFloat("F2",save.f2); outState.putChar("ACHAR",save.achar); outState.putCharArray("ACHARS",save.achars); outState.putIntArray("SSSSS",save.sssss); outState.putIntArray("SASA",save.sasa); outState.putBundle("BUNDLE",save.bundle); } @Override public void recover(Bundle savedInstanceState, MainActivity recover) { if(savedInstanceState != null) { recover.a = savedInstanceState.getInt("A"); recover.test = savedInstanceState.getString("TEST"); recover.c = savedInstanceState.getBoolean("C"); recover.t = (ArrayList<String>)savedInstanceState.getSerializable("T"); recover.i = savedInstanceState.getInt("I"); recover.example = savedInstanceState.getParcelable("EXAMPLE"); recover.f1 = savedInstanceState.getFloat("F1"); recover.f2 = savedInstanceState.getFloat("F2"); recover.achar = savedInstanceState.getChar("ACHAR"); recover.achars = savedInstanceState.getCharArray("ACHARS"); recover.sssss = savedInstanceState.getIntArray("SSSSS"); recover.sasa = savedInstanceState.getIntArray("SASA"); recover.bundle = savedInstanceState.getBundle("BUNDLE"); } } }
基本使用就是以上,欢迎大家使用!