The Android operation configuration file encapsulates the class, which is implemented by json serialization

Posted by devx on Fri, 07 Jan 2022 08:57:19 +0100

Saving some configuration information of an application is a very common function.

SharedPreferences is a lightweight storage class on the Android platform. It is used to save some common configurations of applications. It is easy to use and powerful, but it is not very easy to use in some cases.

For example, only JAVA basic data types are supported, and user-defined data types are not supported. It is saved in / data / data / package as an XML file_ NAME/shared_ In the prefs directory, once the application is uninstalled, it will be uninstalled. It is impossible to keep the configuration or copy the configuration file. (it is a common functional requirement to retain configuration information and copy it on some intelligent terminal devices.)

Although changing the storage location to other directories can be realized by reflection, it is not simple enough.

Previously, there was an operation package for SharedPreferences. See: https://blog.csdn.net/yyz_1987/article/details/104122764

Therefore, it is simple to implement one in the way of json serialization to store files, and it is easier to use.

github address; https://github.com/yangyongzhen/configer.git

For example, to save the IP and port information of a service, use the following:

SysCfg sysCfg = SysCfg.getInstance();

sysCfg.setIP("127.0.0.1");
sysCfg.setPort(5050);
sysCfg.save()

It's as simple as that. You have completed the parameter configuration of IP and Port. SysCfg is a global system parameter configuration class. (the save operation will be stored internally as a json file named SysCfg).

Only the following calls are required when the application starts, that is, the completed deserialization process of loading parameters from file to sysCfg:

SysCfg sysCfg = SysCfg.getInstance();
//Load json configuration information from the file to sysCfg
sysCfg.load();

It's simple enough. Even people who don't know SharedPreferences at all can use them smoothly.

It is much simpler than operating SharedPreferences and sqllite, and you can change the storage location and copy out the configuration file.

In the SysCfg configuration file class, you can define any custom type, which can be stored as long as it can be serialized into json normally.

It is not that your profile class must be SysCfg. This is just an example. It can be defined as any name. You only need to integrate the self encapsulated configger basic class.

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

A complete example is as follows:

package com.yangyongzhen.demo;

import com.yangyongzhen.configer.Configer;
import com.yangyongzhen.configer.Ignore;
/**
SysCfg System configuration class
*/
public class SysCfg extends Configer {
    //Ignore. Ignore annotation is used for those stored without serialization
    @Ignore
    public static final String TAG = SysCfg.class.getSimpleName(); //As the default file name of the configuration file
    @Ignore
    private static SysCfg _instance = null;

    private Integer Ver = 0;				//Version number
    private String Time ="";		//time
    private String PosCode = ""; //Terminal number
    private String UserName = "";		//Login user name
    private String UserPwd = "";			//password

    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);
        //Change the storage directory to mydir, and the default is / Android/data
        Configer.setDirPath("/mydir");
        SysCfg config = SysCfg.getInstance();
        //load
        config.load();
        Log.d(TAG,config.toString());
        //assignment
        config.setVer(500);
        config.setUserName("yangyongzhen");
        //storage
        config.save();
        //Read the test again
        SysCfg config1 = SysCfg.getInstance();
        config1.load();
        Log.d(TAG,config1.toString());

    }

}

Post the implementation of the base class:

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

    /**
     * Initial capital, 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;
    }
}