11[ ![ license] ( https://img.shields.io/badge/license-Apache2.0-brightgreen.svg?style=flat )] ( https://github.com/didi/VirtualAPK/blob/master/LICENSE )
2- [ ![ Release Version] ( https://img.shields.io/badge/release-1.0.0-red.svg )] ( https://bintray.com/noober/maven/AutoSaver )
2+ [ ![ JCenter] ( https://img.shields.io/badge/JCenter-AutoSaver-green.svg?style=flat )] ( https://bintray.com/noober/maven/AutoSaver )
3+
4+
5+ 版本更新说明:
6+
7+ 1.0.0 完成基本功能;
8+ 1.0.1 全局变量的作用域从之前强制public改成只要非private即可;
9+ 1.0.1 修改 SaveHelper.bind(this, savedInstanceState)方法为SaveHelper.recover(this, savedInstanceState),只是重命名,
10+ 以便于理解;
11+ 去掉当内存被收回去调用recover方法时,却没有对应helper类会主动抛异常的情况,方便在BaseAcitviy 和 BaseFragment的
12+ onSaveInstanceState 和 onRestoreInstanceState 统一添加SaveHelper.save和SaveHelper.recover方法。
13+
14+
315# 引入
416
517android 内存被回收是一个开发者的常见问题。当我们** 跳转到一个二级界面,或者切换到后台** 的时候,如果时间过长或者手机的** 内存不足** ,当我们再返回这个界面的时候,activity或fragment就会被内存回收。这时候虽然界面被重新执行了onCreate,但是很多变量的值却已经被置空,这样就导致了很多潜在的bug,已经很多空指针的问题。
618
719其实这种问题需要解决的话也很简单。大家知道,当Activity或者Fragment被内存回收后,我们再进入这个界面,它会自动重新进行onCreate操作,并且系统会帮助我们保存一些值。但是系统只会保存界面上的一些元素,比如textview中的文字,但是很多全局变量仍然会被置空。
820对于保存这些变量,我们可以重写** onSaveInstanceState** 这个方法,在onCreate中即可恢复数据。代码如下:
921 |
10-
11- public int a;
22+
23+ int a;
1224 @Override
1325 protected void onCreate(Bundle savedInstanceState) {
1426 super.onCreate(savedInstanceState);
@@ -30,17 +42,17 @@ android 内存被回收是一个开发者的常见问题。当我们**跳转到
3042 outState.putInt("A", a);
3143 super.onSaveInstanceState(outState);
3244 }
33-
45+
3446通过这样的操作,便可以解决内存回收后变量a的值变为初始值0的问题。
3547
3648问题到这里,似乎已经可以解决内存被回收的问题了。但是随着项目的开发,一个Activity中的变量以及** 代码会变得非常多** ,这时候我们需要去保存某个值就会使代码变得越来越凌乱,同时不断重复的去写outState.putXX已经savedInstanceState.getXX这样的代码都是很重复的,一不小心还会去写错中间的key值。
3749
3850于是我写了这个很轻量级的框架,来解决这个问题。先给出引入这个框架后的代码写法:
3951
4052 @NeedSave
41- public String test;
53+ String test;
4254 @NeedSave
43- private boolean b;
55+ protected boolean b;
4456 @NeedSave
4557 public Boolean c;
4658 @NeedSave
@@ -71,7 +83,7 @@ android 内存被回收是一个开发者的常见问题。当我们**跳转到
7183 super.onCreate(savedInstanceState);
7284 setContentView(R.layout.activity_main);
7385 initData();
74- SaveHelper.bind (this,savedInstanceState);
86+ SaveHelper.recover (this,savedInstanceState);
7587 }
7688
7789 private void initData() {
@@ -83,13 +95,13 @@ android 内存被回收是一个开发者的常见问题。当我们**跳转到
8395 SaveHelper.save(this,outState);
8496 super.onSaveInstanceState(outState);
8597 }
86-
98+
8799这里我特地写了很多的变量,但是无论这个Activity中有多少变量,我在onCreate和onSaveInstanceState代码中都只要去各写一行代码,同时给变量加一个标签标记一个即可:
88100
89101 @NeedSave
90- SaveHelper.bind (this,savedInstanceState);
102+ SaveHelper.recover (this,savedInstanceState);
91103 SaveHelper.save(this,outState);
92-
104+
93105这样就不会因为这种太多的重复的操作去导致代码逻辑的混乱,同时也避免了敲代码时因为key写错导致的错误。
94106
95107# 效果展示
@@ -119,32 +131,34 @@ android 内存被回收是一个开发者的常见问题。当我们**跳转到
119131
120132## @NeedSave
121133
122- 这是一个注解,这个注解只能使用在全局变量中,特别注意,被加上这个注解的变量必须是** public** ,否则会不生效。
134+ 这是一个注解,这个注解只能使用在全局变量中,特别注意,~~ 被加上这个注解的变量必须是** public** ,否则会不生效~~ 。
135+ 1.0.1更新为只要非private即可。
136+
123137当前支持保存的类型有:
124138
125139 String
126- boolean Boolean
140+ boolean Boolean
127141 ArrayList
128142 int int[] Integer
129143 Parcelable
130144 Serializable
131145 float Float
132146 char[] char
133- Bundle
147+ Bundle
134148
135149 注意,如果是Parcelable类型,需要特别在注解中加入 @NeedSave(isParcelable = true) 这样标记
136- ## SaveHelper.bind (this,savedInstanceState);
150+ ## SaveHelper.recover (this,savedInstanceState);
137151这个方法其实是恢复数据的时候去调用的。
138152
139- public static <T> void bind (T recover, Bundle savedInstanceState){
153+ public static <T> void recover (T recover, Bundle savedInstanceState){
140154 if(savedInstanceState != null){
141155 ISaveInstanceStateHelper<T> saveInstanceStateHelper = findSaveHelper(recover);
142156 if(saveInstanceStateHelper != null){
143157 saveInstanceStateHelper.recover(savedInstanceState, recover);
144158 }
145159 }
146160 }
147-
161+
148162savedInstanceState不会null的时候,说明就是需要内存恢复的时候,这时候就会去通过findSaveHelper方法找到一个实现类,然后去调用recover方法恢复数据。
149163## SaveHelper.save(this,outState);
150164这是一个保存数据的方法,** 注意** 的是,这个方法必须在super.onSaveInstanceState(outState);之前调用。
@@ -155,7 +169,7 @@ savedInstanceState不会null的时候,说明就是需要内存恢复的时候
155169 saveInstanceStateHelper.save(outState, save);
156170 }
157171 }
158-
172+
159173它最终调用的是ISaveInstanceStateHelper实现类的save方法。
160174
161175## ISaveInstanceStateHelper实现类
@@ -183,7 +197,7 @@ savedInstanceState不会null的时候,说明就是需要内存恢复的时候
183197 outState.putBundle("BUNDLE",save.bundle);
184198 outState.putInt("A",save.a);
185199 }
186-
200+
187201 @Override
188202 public void recover(Bundle savedInstanceState, MainActivity recover) {
189203 if(savedInstanceState != null) {
@@ -203,13 +217,14 @@ savedInstanceState不会null的时候,说明就是需要内存恢复的时候
203217 }
204218 }
205219 }
206-
220+
207221# 总结
208222看到这里大家已经猜到其实这个框架的实现原理和BufferKnife是相同的。而bufferknife的原理很多文章都有,这里就不过多介绍了。
209223
210224github地址:[ https://github.com/JavaNoober/AutoSave ] ( https://github.com/JavaNoober/AutoSave )
211225
212- 引入方式,在app的gradle中加入下面依赖即可:
226+ 引入方式,在app的gradle中加入下面依赖即可:
227+
213228
214229 compile 'com.noober:savehelper:1.0.0'
215230 compile 'com.noober:savehelper-api:1.0.0'
0 commit comments