Android操作配置文件封装类,使用json序列化的方式实现

简介: Android操作配置文件封装类,使用json序列化的方式实现

保存应用的一些配置信息是很常用的功能。


SharedPreferences是Android平台上一个轻量级的存储类,用来保存应用的一些常用配置,好用且强大,但是某些情况下不是很好用。


比如只支持JAVA基本数据类型,不支持自定义的数据类型。以XML文件的形式保存在 /data/data/PACKAGE_NAME/shared_prefs目录下,应用一旦卸载就跟着卸载了,没法保留配置或者把配置文件拷贝出来。(这在一些智能终端设备上保留配置信息和能够拷贝出来是常用的功能需求。)


虽然改变存储位置为其他目录,可以通过反射的方式实现,但是感觉还是不够简单。


之前有对SharedPreferences的一个操作封装,参见:https://blog.csdn.net/yyz_1987/article/details/104122764


所以,这里以json序列化存储文件的方式简单实现了一个,使用也更简单。


github地址;https://github.com/yangyongzhen/configer.git


举例,想保存个服务的IP和端口信息,使用如下:


SysCfg sysCfg = SysCfg.getInstance();
sysCfg.setIP("127.0.0.1");
sysCfg.setPort(5050);
sysCfg.save()


就这么简单,你已经完成了IP和Port的参数配置,sysCfg 是全局的一个系统参数配置类。(save操作会在内部存储为了一个名称为SysCfg的json文件)。


只需要应用启动时,如下调用,即完成的加载参数从文件到sysCfg反序列化过程:


SysCfg sysCfg = SysCfg.getInstance();
//从文件中加载json配置信息到sysCfg
sysCfg.load();


够简单吧,即使完全不了解SharedPreferences的人也能照葫芦画瓢的顺溜的使用。


比起操作SharedPreferences和sqllite的方式简单多了,而且可以更改存储位置和拷贝出配置文件。


SysCfg 配置文件类里,可以支持定义任何自定义类型,只要它能正常序列化为json都可以存储。


并不是你的配置文件类必须为SysCfg,这里仅是举例。定义成任意名称都可,只需集成自我封装的Configer基础类即可。


How to use?


Add it in your root build.gradle at the end of repositories:
  allprojects {
    repositories {
      ...
      maven { url 'https://jitpack.io' }
    }
  }
Step 2. Add the dependency
  dependencies {
          implementation 'com.github.yangyongzhen:configer:v1.0'
  }


完整示例如下:


package com.yangyongzhen.demo;
import com.yangyongzhen.configer.Configer;
import com.yangyongzhen.configer.Ignore;
/**
SysCfg 系统配置类
*/
public class SysCfg extends Configer {
    //Ignore,不序列化存储的使用Ignore注解
    @Ignore
    public static final String TAG = SysCfg.class.getSimpleName(); //做为配置文件的默认文件名
    @Ignore
    private static SysCfg _instance = null;
    private Integer Ver = 0;        //版本号
    private String Time ="";    //时间
    private String PosCode = ""; //终端编号
    private String UserName = "";   //登录用户名
    private String UserPwd = "";      //密码
    public SysCfg() {
        super(TAG);
    }
    private SysCfg(String filename) {
        super(filename);
    }
    public Integer getVer() {
        return Ver;
    }
    public void setVer(Integer ver) {
        Ver = ver;
    }
    public String getTime() {
        return Time;
    }
    public void setTime(String time) {
        Time = time;
    }
    public String getPosCode() {
        return PosCode;
    }
    public void setPosCode(String posCode) {
        PosCode = posCode;
    }
    public String getUserName() {
        return UserName;
    }
    public void setUserName(String userName) {
        UserName = userName;
    }
    public String getUserPwd() {
        return UserPwd;
    }
    public void setUserPwd(String userPwd) {
        UserPwd = userPwd;
    }
    @Override
    public String toString() {
        return "SysCfg{" +
                "Ver=" + Ver +
                ", Time='" + Time + '\'' +
                ", PosCode='" + PosCode + '\'' +
                ", UserName='" + UserName + '\'' +
                ", UserPwd='" + UserPwd + '\'' +
                '}';
    }
    public static SysCfg getInstance() {
        if (_instance == null) {
            synchronized(SysCfg.class){
                if (_instance == null) {
                    _instance = new SysCfg(TAG);
                }
            }
        }
        return _instance;
    }
}


package com.yangyongzhen.demo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.yangyongzhen.configer.Configer;
public class MainActivity extends AppCompatActivity {
    private final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //更改存储目录为mydir,默认为/Android/data
        Configer.setDirPath("/mydir");
        SysCfg config = SysCfg.getInstance();
        //加载
        config.load();
        Log.d(TAG,config.toString());
        //赋值
        config.setVer(500);
        config.setUserName("yangyongzhen");
        //存储
        config.save();
        //再次读取测试
        SysCfg config1 = SysCfg.getInstance();
        config1.load();
        Log.d(TAG,config1.toString());
    }
}


贴一下基类的实现:


package com.yangyongzhen.configer;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yangyongzhen.configer.utils.FileUtil;
import com.yangyongzhen.configer.utils.GsonUtil;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Configer{
    private static final String TAG = "Configer";
    private static String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();
    private static String dirPath = "/Android/data";
    private transient String filename;
    public Configer(String filename) {
        this.filename = filename;
    }
    public Boolean save(){
        //Log.d(TAG,this.toString());
        String jsStr = GsonUtil.GsonString(this);
        //Log.d(TAG,jsStr);
        Boolean ret = FileUtil.writeFile(rootPath+dirPath,filename,jsStr);
        return ret;
    }
    public Boolean load(){
        Class<?> cls = this.getClass();
        Object rec = null;
        String strfile = FileUtil.readFile(rootPath+dirPath+"/"+filename,"");
        if (!TextUtils.isEmpty(strfile)) {
            JSONObject jsonObject = JSON.parseObject(strfile);
            rec = GsonUtil.deserializer(jsonObject, this.getClass());
            Log.d(TAG,rec.toString());
        }
        if(rec != null){
            Class<?> cls1 = rec.getClass();
            Field[] declaredFields = cls.getDeclaredFields();
            for (int i = 0; i < declaredFields.length; i++) {
                Field field = declaredFields[i];
                if (field.isAnnotationPresent(Ignore.class)) {
                    continue;
                }
                try {
                    Method method = cls1.getDeclaredMethod("get"+upperHeadChar(field.getName()));
                    Object obj = method.invoke(rec);
                    field.setAccessible(true);
                    field.set(this,obj);
                } catch (Exception e) {
                    Log.d(TAG,e.toString());
                    //e.printStackTrace();
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    /**
     * 首字母大写,in:deleteDate,out:DeleteDate
     */
    public static String upperHeadChar(String in) {
        String head = in.substring(0, 1);
        String out = head.toUpperCase() + in.substring(1, in.length());
        return out;
    }
    public static String getRootPath() {
        return rootPath;
    }
    public static void setRootPath(String rootPath) {
        Configer.rootPath = rootPath;
    }
    public static String getDirPath() {
        return dirPath;
    }
    public static void setDirPath(String dirPath) {
        Configer.dirPath = dirPath;
    }
}


相关文章
|
1月前
|
JSON Java Maven
使用Jackson进行 JSON 序列化和反序列化
使用Jackson进行 JSON 序列化和反序列化
27 0
|
1月前
|
JSON Android开发 数据格式
android 使用GSON 序列化对象出现字段被优化问题解决方案
android 使用GSON 序列化对象出现字段被优化问题解决方案
|
1月前
|
存储 JSON 安全
序列化模块pickle和json有什么区别
序列化模块pickle和json有什么区别
18 0
|
2月前
|
JSON fastjson Java
FastJSON操作各种格式的JSON数据
FastJSON处理各种格式的JSON数据
|
2月前
|
JSON 数据格式 C++
[序列化协议] --- JSON
[序列化协议] --- JSON
31 0
|
2月前
|
JSON JavaScript 前端开发
Python之JavaScript逆向系列——接口JSON信息获取与操作
Python之JavaScript逆向系列——接口JSON信息获取与操作
51 0
|
3月前
|
JSON Java fastjson
Java中的JSON序列化和反序列化
Java中的JSON序列化和反序列化
|
3月前
|
JSON 机器人 数据格式
阿里云RPA支持将序列化的JSON数据作为输入参数传递给机器人应用程序
【1月更文挑战第7天】【1月更文挑战第33篇】阿里云RPA支持将序列化的JSON数据作为输入参数传递给机器人应用程序
206 1
|
4月前
|
存储 Java 开发工具
[Android]序列化原理Parcelable
[Android]序列化原理Parcelable
51 0
|
4月前
|
存储 Java Android开发
[Android]序列化原理Serializable
[Android]序列化原理Serializable
46 0