我们通常使用SharedPreferences存储一些需要保存在本地,但又不至于存储在数据库里的一些数据,一般我们用它来存储一些用户名,密码等数据是非常方便的,那么如果我们想要存储的信息有10几条,我们就得写10几行重复的代码把他们存进去,取出来的时候还得写10几行代码将他们一条一条取出来,那么有没有什么办法可以只需要一行代码就可以将他们存进去,一行代码就将他们取出来?答案是有的,这篇文章我们就介绍如何通过反射来实现。
1.将我们想要保存的数据封装成一个实体类 Person.java 其中属性我们都用Public来修饰
public class Person {
//String类型属性 姓名
public String name;
//int类型属性 年龄
public int age;
//float类型属性 身高
public float height;
//boolean类型属性 是否已婚
public boolean isMarried;
//String类型属性 证件号
public String id;
}
2.通过反射,将Person类中的属性取出来
public class SharedPreferencesUtils {
/**
* 根据传入的对象,取出其中用public修饰符修饰的属性
* @param clazz 想要拿到属性的类的字节码文件
* @return 所有用pulic修饰的属性的一个list表
*/
public static
List
getPublicFields(Class
clazz){
if (clazz.equals(Object.class)) {
return null;
}
//用来存储clazz中用public修饰的属性的list
List
list = new ArrayList
();
//获得clazz中所有用public修饰的属性
Field[] fields = clazz.getFields();
//将fields加入到list中
for(int i=0 ; i
我们先来测试一下属性有没有被取出来,我们在MainActivity.java中添加如下代码进行测试
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//调用我们刚刚写好的方法来获取Person类中的属性
List
publicFields = SharedPreferencesUtils.getPublicFields(Person.class);
for(Field f : publicFields){
String name = f.getName();
Log.i("TAG", name+"\n");
}
}
}
我们来看一下Log打印的信息
我们可以看到,Person中的属性我们都已经拿到了
3.将对象存储到SharedPreferences中
public static void putObjectToShare(String shareName , Object obj){
//获得SharedPreferences实例
SharedPreferences sharedPreferences = mContext.getSharedPreferences(shareName,Activity.MODE_PRIVATE);
//获得Editor
Editor edit = sharedPreferences.edit();
//存储数据之前先将之前的旧数据清掉
edit.clear();
//调用commit提交数据(这里为了清掉数据)
edit.commit();
List
publicFields = getPublicFields(obj.getClass());
for(Field f : publicFields){
String name = f.getName();
try {
//获得当前属性的类型和值
//类型的话如果是基本类型,会自动装箱
Object type = f.get(obj);
//判断各种类型,调用各种类型的put方法将数据存储进去
if (type instanceof String) {
edit.putString(name, (String) type);
}else if (type instanceof Integer) {
edit.putInt(name, (Integer) type);
}else if (type instanceof Float) {
edit.putFloat(name, (Float) type);
}else if (type instanceof Long) {
edit.putLong(name, (Long) type);
}else if (type instanceof Boolean) {
edit.putBoolean(name, (Boolean) type);
}
} catch (Exception e) {
e.printStackTrace();
}
//调用commit,提交数据
edit.commit();
}
}
4.将对象从SharedPreferences中取出来
public static
T getObjectFromShare(String shareName , Class
clazz){
//获得SharedPreferences实例
SharedPreferences sharedPreferences = mContext.getSharedPreferences(shareName, Activity.MODE_PRIVATE);
//T是一个泛型,根据clazz不同而不同
T t = null;
try {
//获得sharedPreferences中所有的数据,数据为键值对保存在map中
Map
map = sharedPreferences.getAll();
//调用getPublicFields方法得到clazz中所有的公有属性
List
publicFields = getPublicFields(clazz);
//如果两者都不为空的话
if (map.size()>0 && publicFields.size()>0) {
//将T实例化出来
t = clazz.newInstance();
//遍历map中所有的键值对
for(Map.Entry
entry : map.entrySet()){ //map中的键 String key = entry.getKey(); //map中的值 Object value = entry.getValue(); //遍历clazz中的所有公有属性 for(Field field : publicFields){ //获得属性名 String name = field.getName(); //如果属性名与键相同 if (name.equalsIgnoreCase(key)) { //相当于给对象T中的属性field赋值,值为value field.set(t, value); break; } } } } } catch (Exception e) { e.printStackTrace(); } //整个遍历结束后,我们的对象中的属性也都有值了 return t; }
5.我们来测试一下,修改MainAcitvity.java中的代码
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//实例化一个Person实例,这是我们想要存储到SharedPreferences中的对象
Person p = new Person("zhangsan",23,175.0f,false,"001");
//将p存储到SharedPreferences的“zhangqi”名下
SharedPreferencesUtils.getInstance(this).putObjectToShare("zhangqi",p);;
//从SharedPreferences的“zhangqi”名下取出之前存储过的Person实例
Person savedPerson = SharedPreferencesUtils.getInstance(this).getObjectFromShare("zhangqi",Person.class);
Log.e("zhangqi",""+savedPerson.toString());
}
}
我们看一下Log中打印的savedPerson的信息