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


相关文章
|
5月前
|
JSON 算法 vr&ar
目标检测笔记(五):查看通过COCOEvaluator生成的coco_instances_results.json文件的详细检测信息,包含AP、AR、MR和DR等
本文介绍了如何使用COCO评估器通过Detectron2库对目标检测模型进行性能评估,生成coco_instances_results.json文件,并利用pycocotools解析该文件以计算AP、AR、MR和DR等关键指标。
293 1
目标检测笔记(五):查看通过COCOEvaluator生成的coco_instances_results.json文件的详细检测信息,包含AP、AR、MR和DR等
|
1月前
|
开发工具 git 索引
怎么取消对project.private.config.json这个文件的git记录
通过以上步骤,您可以成功取消对 `project.private.config.json`文件的Git记录。这样,文件将不会被包含在未来的提交中,同时仍保留在您的工作区中。
61 28
|
2月前
|
JSON 小程序 UED
微信小程序 app.json 配置文件解析与应用
本文介绍了微信小程序中 `app.json` 配置文件的详细
195 12
|
7月前
|
JSON API 网络架构
【Azure 媒体服务】使用编码预设文件(Preset.json)来自定义编码任务 -- 创建视频缩略图
【Azure 媒体服务】使用编码预设文件(Preset.json)来自定义编码任务 -- 创建视频缩略图
|
7月前
|
JavaScript 前端开发 编译器
10min代码快速熟悉Tsconfig.json配置文件
【8月更文挑战第16天】10min代码快速熟悉Tsconfig.json配置文件
201 2
|
6月前
|
XML JSON JavaScript
R JSON 文件
JSON: JavaScript Object Notation(JavaScript 对象表示法)。
94 29
|
5月前
|
JSON 数据格式 Python
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
这篇文章介绍了一个Python脚本,用于统计TXT或JSON文件中特定单词的出现次数。它包含两个函数,分别处理文本和JSON文件,并通过命令行参数接收文件路径、目标单词和文件格式。文章还提供了代码逻辑的解释和示例用法。
77 0
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
|
5月前
|
JSON JavaScript API
(API接口系列)商品详情数据封装接口json数据格式分析
在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦!
|
5月前
|
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向量化 增强检索
336 2
|
6月前
|
JSON 前端开发 JavaScript
java中post请求调用下载文件接口浏览器未弹窗而是返回一堆json,为啥
客户端调接口需要返回另存为弹窗,下载文件,但是遇到的问题是接口调用成功且不报错,浏览器F12查看居然返回一堆json,而没有另存为弹窗; > 正确的效果应该是:接口调用成功且浏览器F12不返回任何json,而是弹窗另存为窗口,直接保存文件即可。
221 2

热门文章

最新文章

  • 1
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 2
    Android历史版本与APK文件结构
  • 3
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
  • 4
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
  • 10
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥