首页 > 其他分享 >【android】Android通过反射打造可以存储任何对象的万能SharedPreferences

【android】Android通过反射打造可以存储任何对象的万能SharedPreferences

时间:2023-02-06 11:13:33浏览次数:58  
标签:String public Person SharedPreferences android clazz Android 属性

我们通常使用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的信息

 

 

 【参考连接】

Android通过反射打造可以存储任何对象的万能SharedPreferences

 

   

标签:String,public,Person,SharedPreferences,android,clazz,Android,属性
From: https://www.cnblogs.com/opensmarty/p/17094762.html

相关文章

  • android开发技巧杂谈
    android开发技巧一android的一些常用包是发布在国外的,所以一些包,我们下载不下来,我们可以使用阿里云的镜像地址(maven{url'https://maven.aliyun.com/nexus/content/grou......
  • Android集成mupdf,实现手写笔签字,手指翻页的java代码
    importandroid.graphics.Bitmap;importandroid.graphics.Color;importandroid.graphics.RectF;importandroid.util.Log;importjava.util.LinkedList;importc......
  • 【Delphi】Android 程序权限详细说明
    转载https://blog.csdn.net/sensor_WU/article/details/125749637 【Delphi】Android程序权限详细说明sensor_WU已于2022-07-1407:17:19修改739收藏1分类专栏:De......
  • Android 使用腾讯地图定位地点
    Android利用和风天气API显示实时天气-拾一贰叁-博客园(cnblogs.com)之前使用和风天气的SDK在AndroidApp上显示了实时天气情况,但是显示的地点信息是提前设置好的因......
  • Android笔记--内容提供者+Server端+Client端
    什么是内容提供者ContentProvider为App存取内部数据提供的统一的外部接口,让不同的应用之间得以实现数据共享ClientApp端用户输入数据的一端,或者说是用户读取到存储的数......
  • Android RecyclerView实现ViewPager效果,用LinearSnapHelper
    文章目录​​LinearSnapHelper效果​​LinearSnapHelper效果SnapHelper是RecyclerView功能的一种拓展,使RecyclerView滑动行为类似ViewPager,无论怎么滑动最终停留在某页正中......
  • Android 动画
    在App中合理地使用动画能够获得友好愉悦的用户体验,Android中的动画有View动画、属性动画、帧动画、布局动画、转场动画等,在5.x以后有又新增了矢量动画,这些动画在平常开发中......
  • 65Android 调试桥 (adb)命令
    Android调试桥(adb)网络连接通过TCP/IP连接设备adbconnect<ip:port>断开已有的TCP/IP连接adbdisconnect<ip:port>监听设备上指定的端口号adbtcpip<port>......
  • Android笔记--Room增删改查
    添加查询删除修改......
  • Android笔记--Jetpack Room
    JetpackRoom使用Room简化数据库操作:(基于SQLite)在使用Room之前:使用Room框架有以下几个步骤:1、实体类加@Entity注解@PrimaryKey(autoGenerate=true)是自动增长的意......