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;
    }
}


相关文章
|
3月前
|
JSON 算法 vr&ar
目标检测笔记(五):查看通过COCOEvaluator生成的coco_instances_results.json文件的详细检测信息,包含AP、AR、MR和DR等
本文介绍了如何使用COCO评估器通过Detectron2库对目标检测模型进行性能评估,生成coco_instances_results.json文件,并利用pycocotools解析该文件以计算AP、AR、MR和DR等关键指标。
181 1
目标检测笔记(五):查看通过COCOEvaluator生成的coco_instances_results.json文件的详细检测信息,包含AP、AR、MR和DR等
|
5月前
|
JSON API 网络架构
【Azure 媒体服务】使用编码预设文件(Preset.json)来自定义编码任务 -- 创建视频缩略图
【Azure 媒体服务】使用编码预设文件(Preset.json)来自定义编码任务 -- 创建视频缩略图
|
3月前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
44 1
|
3月前
|
JSON 数据格式 Python
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
这篇文章介绍了一个Python脚本,用于统计TXT或JSON文件中特定单词的出现次数。它包含两个函数,分别处理文本和JSON文件,并通过命令行参数接收文件路径、目标单词和文件格式。文章还提供了代码逻辑的解释和示例用法。
56 0
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
|
4月前
|
XML JSON JavaScript
R JSON 文件
JSON: JavaScript Object Notation(JavaScript 对象表示法)。
82 29
|
2月前
|
前端开发 Java 测试技术
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
81 0
|
3月前
|
前端开发 Java 测试技术
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
34 2
|
3月前
|
JSON 数据格式
LangChain-20 Document Loader 文件加载 加载MD DOCX EXCEL PPT PDF HTML JSON 等多种文件格式 后续可通过FAISS向量化 增强检索
LangChain-20 Document Loader 文件加载 加载MD DOCX EXCEL PPT PDF HTML JSON 等多种文件格式 后续可通过FAISS向量化 增强检索
165 2
|
4月前
|
JSON 前端开发 中间件
React读取properties配置文件转化为json对象并使用在url地址中
本文介绍了如何在React项目中读取properties配置文件,将其内容转化为JSON对象,并在请求URL地址时使用这些配置。文章详细说明了异步读取文件、处理字符串转换为JSON对象的过程,并提供了一个封装函数,用于在发起请求前动态生成配置化的URL地址。
103 1
|
4月前
|
JSON 前端开发 JavaScript
java中post请求调用下载文件接口浏览器未弹窗而是返回一堆json,为啥
客户端调接口需要返回另存为弹窗,下载文件,但是遇到的问题是接口调用成功且不报错,浏览器F12查看居然返回一堆json,而没有另存为弹窗; > 正确的效果应该是:接口调用成功且浏览器F12不返回任何json,而是弹窗另存为窗口,直接保存文件即可。
176 2

热门文章

最新文章