应用程序中将用户默认的设置参数存入本地数据库的一种处理方式,以ObjectBox为例

       一般情况下,应用中都会有些默认的配置信息,我们也会把用户的设置信息,比如某些开关按钮的状态等这些轻量级的数据,存入SharedPreferences文件中,本文尝试换一种实现的方式,将这些默认数据存入本地数据库中,同时希望在应用的不同版本开发过程中,能够尽量方便、简单的处理这些数据的增删改查操作。

       将用户的默认配置信息写入在json文件中,这些数据会在应用启动用户登录后写入到数据库,并且在以后应用的各版本开发当中,只需要操作相关的 json 文件,就可以实现在数据库中增加、修改、删除某些配置信息,

       示例代码以ObjectBox数据库为例,本文只是提供一种实现的思路,仅供参考。

 

json文件示例如下:

配置信息的 user_config.json 文件:

[
  {
    "pkey": "user_setting",
    "ckey": "",
    "value": 0,
    "version": 1,
    "operationType": 1
  },
  {
    "pkey": "app_setting",
    "ckey": "",
    "value": 0,
    "version": 1,
    "operationType": 1
  },
  {
    "pkey": "notify",
    "ckey": "app_setting",
    "value": 1,
    "version": 1,
    "operationType": 1
  },
  {
    "pkey": "voice",
    "ckey": "user_setting",
    "value": 1,
    "version": 1,
    "operationType": 1
  },
  {
    "pkey": "vibrate",
    "ckey": "user_setting",
    "value": 1,
    "version": 1,
    "operationType": 1
  }
]

本示例 json 中的数据结构采用了多级分类的关系,数据库也是这样存储,具体以自己的实际需求为准,"pkey" 有唯一性,每一个配置都需要有一个唯一的名称,"ckey" 是与自己归属的上级分类相关联;"value",约定值,代表配置的状态值,如开关按钮的打开、关闭状态;"version" 代表版本号,"operationType",约定值,代表对当前这个对象的操作类型,新增、删除等。

表对应的版本号的 table_version.json 文件:

{
  "user_config_entity": 1
}

以map的形式存储表对应的版本号,约定的将 "user_config_entity" 与 用户配置信息表相对应,假如有其它类似功能需求,这个集合中也可以再增加其它表对应的版本信息。

当用户首次初始化自己的配置信息的时候,会先解析json文件,将这些默认的数据存储到本地数据库;

当后续应用已经开发到了其它版本,假如应用在开发版本6的时候需要添加一个新的按钮的默认数据,只需要在 user_config.json 文件中加入一个json 对象即可,如:

{
    "pkey": "message",
    "ckey": "user_setting",
    "value": 1,
    "version": 2,
    "operationType": 1
  }

注意,这里必须要修改 "version" 这个字段值,要比之前的版本大,同时要修改 table_version.json 中 "user_config_entity" 表的版本号,一定要保证这两个值一致,这个版本号是我们自己定义的,与实际使用的数据库版本号没有任何关系,是用来标识我们的配置信息数据是否有新的数据需要处理;另外约定的 operationType = 1代表数据库中会新增这条数据。

假如应用在开发版本6的时候需要删除一个旧的按钮的数据,同样需要像上面一样修改版本号,operationType = 2代表数据库中会删除这条数据。

另外我们也可以将版本号的值都降低,也是可以的,根据自己对不同配置数据的需求进行处理即可。

       通过操作json文件,就实现了在数据库中增加、修改、删除这些配置信息,这其中一个重要的依赖字段是 "operationType" ,它可以帮助我们方便的在业务处理时判断是新增、修改还是删除等操作;

       而后续应用的版本还会不断的迭代,不同的版本这些配置信息很可能会发生化,有的新增,有的删除,为了能尽可能的只处理当前开发版本所涉及的数据,同时用户所安装的应用可能有跨版本升级的情况,这就是 "version" 字段 和 "table_version" 的意义。

下面主要看一下在页面处理逻辑:

package com.windfallsheng.handleuserconfiginfos.view;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import com.windfallsheng.handleuserconfiginfos.Constants;
import com.windfallsheng.handleuserconfiginfos.R;
import com.windfallsheng.handleuserconfiginfos.db.manager.UserConfigManager;
import com.windfallsheng.handleuserconfiginfos.db.UserConfigService;
import com.windfallsheng.handleuserconfiginfos.db.entity.UserConfigEntity;
import com.windfallsheng.handleuserconfiginfos.widget.SwitchButton;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private SwitchButton mSwitchBtnNotify, mSwitchBtnVoice, mSwitchBtnVibrate;
    private TextView mTvNotify, mTvVoice, mTvVibrate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //
        mSwitchBtnNotify = findViewById(R.id.switchbutton_notify);
        mSwitchBtnVoice = findViewById(R.id.switchbutton_voice);
        mSwitchBtnVibrate = findViewById(R.id.switchbutton_vibrate);
        mTvNotify = findViewById(R.id.textview_notify_status);
        mTvVoice = findViewById(R.id.textview_voice_status);
        mTvVibrate = findViewById(R.id.textview_vibrate_status);

        // 初始化相关配置信息
        UserConfigService userConfigService = new UserConfigService(this);
        userConfigService.initUserConfig();

        // 通知设置
        final UserConfigEntity notifyConfig = UserConfigManager.getInstance().queryUserConfigByKey(Constants.CONFIG_KEY_NOTIFY);
        Log.d(TAG, "method:onCreate#notifyConfig=" + notifyConfig);
        if (notifyConfig == null) {
            mTvNotify.setText(getResources().getString(R.string.config_delete));
        } else {
            int notifyValue = notifyConfig.getValue();
            Log.d(TAG, "method:onCreate#notifyValue=" + notifyValue);
            final boolean notifyChecked = notifyValue == Constants.SWITCH_ON ? true : false;
            mSwitchBtnNotify.setChecked(notifyChecked);
            // 监听事件
            mSwitchBtnNotify.setOnCheckedChangeListener(new SwitchButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(SwitchButton view, boolean isChecked) {
                    Log.d(TAG, "method:onCreate#notifyChecked=" + notifyChecked + ", isChecked=" + isChecked);
                    int switchStatus = isChecked == true ? Constants.SWITCH_ON : Constants.SWITCH_OFF;
                    notifyConfig.setValue(switchStatus);
                    UserConfigManager.getInstance().updateUserConfig(notifyConfig);
                }
            });
        }

        // 声音设置
        final UserConfigEntity voiceConfig = UserConfigManager.getInstance().queryUserConfigByKey(Constants.CONFIG_KEY_VOICE);
        Log.d(TAG, "method:onCreate#voiceConfig=" + voiceConfig);
        if (voiceConfig == null) {
            mTvVoice.setText(getResources().getString(R.string.config_delete));
        } else {
            final int voiceValue = voiceConfig.getValue();
            Log.d(TAG, "method:onCreate#voiceValue=" + voiceValue);
            final boolean voiceChecked = voiceValue == Constants.SWITCH_ON ? true : false;
            mSwitchBtnVoice.setChecked(voiceChecked);
            // 监听事件
            mSwitchBtnVoice.setOnCheckedChangeListener(new SwitchButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(SwitchButton view, boolean isChecked) {
                    Log.d(TAG, "method:onCreate#voiceChecked=" + voiceChecked + ", isChecked=" + isChecked);
                    int switchStatus = isChecked == true ? Constants.SWITCH_ON : Constants.SWITCH_OFF;
                    voiceConfig.setValue(switchStatus);
                    UserConfigManager.getInstance().updateUserConfig(voiceConfig);
                }
            });
        }

        // 震动设置
        final UserConfigEntity vibrateConfig = UserConfigManager.getInstance().queryUserConfigByKey(Constants.CONFIG_KEY_VIBRATE);
        Log.d(TAG, "method:onCreate#vibrateConfig=" + vibrateConfig);
        if (vibrateConfig == null) {
            mTvVibrate.setText(getResources().getString(R.string.config_delete));
        } else {
            final int vibrateValue = vibrateConfig.getValue();
            Log.d(TAG, "method:onCreate#vibrateValue=" + vibrateValue);
            final boolean vibrateChecked = vibrateValue == Constants.SWITCH_ON ? true : false;
            mSwitchBtnVibrate.setChecked(vibrateChecked);
            // 监听事件
            mSwitchBtnVibrate.setOnCheckedChangeListener(new SwitchButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(SwitchButton view, boolean isChecked) {
                    Log.d(TAG, "method:onCreate#vibrateChecked=" + vibrateChecked + ", isChecked=" + isChecked);
                    int switchStatus = isChecked == true ? Constants.SWITCH_ON : Constants.SWITCH_OFF;
                    vibrateConfig.setValue(switchStatus);
                    UserConfigManager.getInstance().updateUserConfig(vibrateConfig);
                }
            });
        }
    }
}

数据库实体类如下:

package com.windfallsheng.handleuserconfiginfos.db.entity;

import java.io.Serializable;
import io.objectbox.annotation.Entity;
import io.objectbox.annotation.Id;
import io.objectbox.annotation.Index;
import io.objectbox.annotation.NameInDb;

/**
 * @author lzsheng
 * 用户个人的设置数据表
 */
@Entity
public class UserConfigEntity implements Serializable {

    @Id
    private long id;
    /**
     * 设置字段的key
     */
    @Index
    @NameInDb("pkey")
    private String pkey;
    /**
     * 关联主键{@link UserConfigEntity#pkey}的字段
     */
    @NameInDb("ckey")
    private String ckey;
    /**
     * 设置字段的value
     */
    @NameInDb("value")
    private int value;
    /**
     * 最近修改时间
     */
    @NameInDb("modify_time")
    private long modifyTime;
    /**
     * 该数据做修改操作时对应的表版本号
     */
    @NameInDb("version")
    private int version;
    /**
     * 对该字段进行的操作的类型:修改、删除等
     */
    @NameInDb("operation_type")
    private int operationType;

    public UserConfigEntity() {
    }

    public UserConfigEntity(long id, String pkey, String ckey, int value, long modifyTime, int version, int operationType) {
        this.id = id;
        this.pkey = pkey;
        this.ckey = ckey;
        this.value = value;
        this.modifyTime = modifyTime;
        this.version = version;
        this.operationType = operationType;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getPkey() {
        return pkey;
    }

    public void setPkey(String pkey) {
        this.pkey = pkey;
    }

    public String getCkey() {
        return ckey;
    }

    public void setCkey(String ckey) {
        this.ckey = ckey;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public long getModifyTime() {
        return modifyTime;
    }

    public void setModifyTime(long modifyTime) {
        this.modifyTime = modifyTime;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public int getOperationType() {
        return operationType;
    }

    public void setOperationType(int operationType) {
        this.operationType = operationType;
    }

    @Override
    public String toString() {
        return "UserConfigEntity{" +
                "id=" + id +
                ", pkey='" + pkey + '\'' +
                ", ckey='" + ckey + '\'' +
                ", value=" + value +
                ", modifyTime=" + modifyTime +
                ", version=" + version +
                ", operationType=" + operationType +
                '}';
    }
}
package com.windfallsheng.handleuserconfiginfos.db.entity;

import java.io.Serializable;
import io.objectbox.annotation.Entity;
import io.objectbox.annotation.Id;
import io.objectbox.annotation.Index;
import io.objectbox.annotation.NameInDb;
import io.objectbox.annotation.Unique;

/**
 * @author lzsheng
 * 数据表及版本号
 */
@Entity
public class TableVersionEntity implements Serializable {

    @Id
    private long id;
    @Index
    @NameInDb("table_name")
    /**
     *  表名,每个表对应唯一的表名
     */
    @Unique
    private String tableName;
    /**
     * 该表对应的当前版本
     */
    @NameInDb("version_code")
    private int versionCode;

    public TableVersionEntity() {
    }

    public TableVersionEntity(long id, String tableName, int versionCode) {
        this.id = id;
        this.tableName = tableName;
        this.versionCode = versionCode;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public int getVersionCode() {
        return versionCode;
    }

    public void setVersionCode(int versionCode) {
        this.versionCode = versionCode;
    }

    @Override
    public String toString() {
        return "TableVersionEntity{" +
                "id=" + id +
                ", tableName='" + tableName + '\'' +
                ", versionCode=" + versionCode +
                '}';
    }
}

以下是数据库业务操作相关类的代码

用户配置数据的数据库操作类:

package com.windfallsheng.handleuserconfiginfos.db.manager;

import android.text.TextUtils;
import android.util.Log;
import com.windfallsheng.handleuserconfiginfos.db.ObjectBox;
import com.windfallsheng.handleuserconfiginfos.db.entity.UserConfigEntity;
import com.windfallsheng.handleuserconfiginfos.db.entity.UserConfigEntity_;
import java.util.List;
import io.objectbox.Box;

/**
 * @author lzsheng
 *
 * {@link UserConfigEntity}的CRUD操作
 */
public class UserConfigManager {

    private static final String TAG = UserConfigManager.class.getSimpleName();
    private static volatile UserConfigManager instance = null;
    private static Box<UserConfigEntity> mUserConfigEntityBox;

    private UserConfigManager() {

    }

    public static UserConfigManager getInstance() {
        if (instance == null) {
            synchronized (UserConfigManager.class) {
                if (instance == null) {
                    instance = new UserConfigManager();
                    mUserConfigEntityBox = ObjectBox.getBoxStore().boxFor(UserConfigEntity.class);
                }
            }
        }
        return instance;
    }

    public void insertUserConfigList(List<UserConfigEntity> userConfigList) {
        Log.d(TAG, "method:insertUserConfigList#userConfigList=" + userConfigList.toString());
        if (userConfigList == null) {
            throw new IllegalArgumentException("userConfigList = null");
        }
        mUserConfigEntityBox.put(userConfigList);
    }

    public long insertOrReplaceUserConfig(UserConfigEntity userConfig) {
        Log.d(TAG, "method:insertOrReplaceUserConfig#userConfig=" + userConfig);
        if (userConfig == null) {
            throw new IllegalArgumentException("userConfig = null");
        }
        UserConfigEntity userConfigEntity = queryUserConfigByKey(userConfig.getPkey());
        if (userConfigEntity != null){
            long id = userConfigEntity.getId();
            Log.d(TAG, "method:insertOrReplaceUserConfig#userConfigEntity#id=" + id);
            userConfig.setId(id);
        }
        long putId = mUserConfigEntityBox.put(userConfig);
        Log.d(TAG, "method:insertOrReplaceUserConfig#putId=" + putId);
        return putId;
    }

    public long updateUserConfig(UserConfigEntity userConfig) {
        Log.d(TAG, "method:updateUserConfig#userConfig=" + userConfig);
        if (userConfig == null) {
            throw new IllegalArgumentException("userConfig = null");
        }
        long putId = mUserConfigEntityBox.put(userConfig);
        Log.d(TAG, "method:updateUserConfig#putId=" + putId);
        return putId;
    }

    /**
     * 查询数据
     *
     * @return
     */
    public UserConfigEntity queryUserConfigByKey(String pkey) {
        Log.d(TAG, "queryUserConfigByKey#pkey=" + pkey);
        if (TextUtils.isEmpty(pkey)) {
            return null;
        }
        UserConfigEntity userConfigEntity = mUserConfigEntityBox
                .query()
                .equal(UserConfigEntity_.pkey, pkey)
                .build()
                .findUnique();
        return userConfigEntity;
    }

    /**
     * 查询所有配置数据
     *
     * @return
     */
    public List<UserConfigEntity> queryAllUserConfig() {
        Log.d(TAG, "queryAllUserConfig");
        List<UserConfigEntity> userConfigList = mUserConfigEntityBox
                .query()
                .build()
                .find();
        return userConfigList;
    }

    public long queryCountUserConfig() {
        long count = mUserConfigEntityBox
                .query()
                .build()
                .count();
        return count;
    }

    public long deleteUserConfigByKey(String pkey) {
        Log.d(TAG, "method:deleteUserConfigByKey#pkey=" + pkey);
        if (TextUtils.isEmpty(pkey)) {
            throw new IllegalArgumentException("pkey is empty.");
        }
        long removeRowId = mUserConfigEntityBox
                .query()
                .equal(UserConfigEntity_.pkey, pkey)
                .build()
                .remove();
        Log.d(TAG, "method:deleteUserConfigByKey#removeRowId=" + removeRowId);
        return removeRowId;
    }
}

 表的版本信息的数据库操作类:

package com.windfallsheng.handleuserconfiginfos.db.manager;

import android.text.TextUtils;
import android.util.Log;
import com.windfallsheng.handleuserconfiginfos.db.ObjectBox;
import com.windfallsheng.handleuserconfiginfos.db.entity.TableVersionEntity;
import com.windfallsheng.handleuserconfiginfos.db.entity.TableVersionEntity_;
import java.util.List;
import io.objectbox.Box;

/**
 * @author lzsheng
 * <p>
 * {@link TableVersionEntity}的CRUD操作
 */
public class TableVersionManager {

    private static final String TAG = TableVersionManager.class.getSimpleName();
    private static volatile TableVersionManager instance = null;
    private static Box<TableVersionEntity> mUserConfigEntityBox;


    private TableVersionManager() {

    }

    public static TableVersionManager getInstance() {
        if (instance == null) {
            synchronized (TableVersionManager.class) {
                if (instance == null) {
                    instance = new TableVersionManager();
                    mUserConfigEntityBox = ObjectBox.getBoxStore().boxFor(TableVersionEntity.class);
                }
            }
        }
        return instance;
    }

    public void insertOrReplaceTableVersion(TableVersionEntity tableVersion) {
        Log.d(TAG, "insertOrReplaceTableVersion#tableVersion=" + tableVersion);
        if (tableVersion == null) {
            throw new IllegalArgumentException("tableVersion = null");
        }
        long putId = mUserConfigEntityBox
                .put(tableVersion);
    }

    /**
     * 查询数据
     *
     * @return
     */
    public TableVersionEntity queryTableInfosByTableName(String tableName) {
        Log.d(TAG, "method:queryTableInfosByTableName#argument:tableName=" + tableName);
        if (TextUtils.isEmpty(tableName)) {
            throw new IllegalArgumentException("tableName is empty");
        }
        TableVersionEntity tableVersionEntity = mUserConfigEntityBox
                .query()
                .equal(TableVersionEntity_.tableName, tableName)
                .build()
                .findUnique();
        return tableVersionEntity;
    }

    public List<TableVersionEntity> queryAllTableVersion() {
        Log.d(TAG, "queryAllTableVersion");
        List<TableVersionEntity> tableVersionList = mUserConfigEntityBox
                .query()
                .build()
                .find();
        return tableVersionList;
    }

    public void deleteTableVersionByTableName(String tableName) {
        Log.d(TAG, "deleteTableVersionByTableName#tableName=" + tableName);
        if (TextUtils.isEmpty(tableName)) {
            throw new IllegalArgumentException("tableName is empty");
        }
        long removeId = mUserConfigEntityBox
                .query()
                .equal(TableVersionEntity_.tableName, tableName)
                .build()
                .remove();
    }

}

 UserConfigService 类处理json文件数据和数据库数据的交互业务,根据最新的数据判断如何处理

package com.windfallsheng.handleuserconfiginfos.db;

import android.content.Context;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.windfallsheng.handleuserconfiginfos.Constants;
import com.windfallsheng.handleuserconfiginfos.Util.ResUtils;
import com.windfallsheng.handleuserconfiginfos.db.entity.TableVersionEntity;
import com.windfallsheng.handleuserconfiginfos.db.entity.UserConfigEntity;
import com.windfallsheng.handleuserconfiginfos.db.manager.TableVersionManager;
import com.windfallsheng.handleuserconfiginfos.db.manager.UserConfigManager;
import java.util.List;
import java.util.Map;

/**
 * @author lzsheng
 * 设置表的相关业务操作包括:
 * 初始化用户设置的原始数据;更新数据库中对应的表的版本号等
 */
public class UserConfigService {
    private static final String TAG = UserConfigService.class.getSimpleName();
    private Context mContext;

    public UserConfigService(Context context) {
        if (context == null) {
            throw new IllegalArgumentException("context = null");
        }
        this.mContext = context.getApplicationContext();
    }

    /**
     * 初始化用户设置的原始数据,业务操作与设置表的版本号相关
     */
    public void initUserConfig() {
        Log.d(TAG, "method:initUserConfig#in");
        printData();
        // 获取配置文件中最新的版本信息
        Map<String, Integer> newTableVersionMap = parseNewTableVersionMap();
        // 获取json配置文件中最新的版本号
        int newTableVersionCode = newTableVersionMap.get(Constants.TABLE_NAME_USER_CONFIG);
        // 获取数据库中上一个版本信息
        TableVersionEntity tableVersionEntity = TableVersionManager.getInstance().queryTableInfosByTableName(Constants.TABLE_NAME_USER_CONFIG);
        Log.d(TAG, "method:initUserConfig#tableVersionEntity=" + tableVersionEntity + ", newVersionCode=" + newTableVersionCode + ", newTableVersionMap=" + newTableVersionMap);
        // 当数据库中没有该表的版本号,说明还没有插入过任何数据,则可以直接向数据库插入所有数据
        if (tableVersionEntity == null) {
            List<UserConfigEntity> newUserConfigList = parseNewUserConfigList();
            // 剔除不需要新增或者修改的对象
            int size = newUserConfigList.size();
            for (int i = 0; i < size; i++) {
                UserConfigEntity userConfigEntity = newUserConfigList.get(i);
                if (userConfigEntity.getOperationType() != Constants.USER_CONFIG_FIELD_OPERATION_TYPE_INSERT_OR_UPDATE) {
                    newUserConfigList.remove(i);
                    i--;
                    size--;
                }
            }
            UserConfigManager.getInstance().insertUserConfigList(newUserConfigList);
            // 更新数据库中的版本信息为最新版本
//            if (...) { // 这里可以做一些验证,保证数据库的操作都正确之后再更新这个表的字段
            updateTableVersion(0, Constants.TABLE_NAME_USER_CONFIG, newTableVersionCode);
//            }
            printData();
            return;
        }
        // 当数据库中有该表的版本号时,则需要判断版本号的大小,是否需要处理新数据
        int lastTableVersionCode = tableVersionEntity.getVersionCode();
        Log.d(TAG, "method:initUserConfig#lastTableVersionCode=" + lastTableVersionCode + ", newTableVersionCode=" + newTableVersionCode);
        // 当前数据库中的数据版本和最新数据的版本号相同,不需要处理新数据
        if (newTableVersionCode == lastTableVersionCode) {
            printData();
            Log.d(TAG, "method:initUserConfig#return#newTableVersionCode == lastTableVersionCode");
            return;
        }
        List<UserConfigEntity> newUserConfigList = parseNewUserConfigList();
        // 升级操作:当前数据库中的数据版本小于最新数据的版本,需要处理新数据
        if (newTableVersionCode > lastTableVersionCode) {
            for (int i = 0; i < newUserConfigList.size(); i++) {
                UserConfigEntity newUserConfig = newUserConfigList.get(i);
                // 该数据的版本号
                int newFieldVersionCode = newUserConfig.getVersion();
                // 该数据的版本号大于上一个版本时,根据操作类型修改,或者删除
                if (newFieldVersionCode > lastTableVersionCode) {
                    //根据数据的操作类型调用相应的修改和删除操作等
                    handleUserConfigByOperationType(newUserConfig);
                }
            }
            // 更新数据库中的版本信息为最新版本
//            if (...) { // 这里可以做一些验证,保证数据库的操作都正确之后再更新这个表的字段
            updateTableVersion(tableVersionEntity.getId(), Constants.TABLE_NAME_USER_CONFIG, newTableVersionCode);
//            }
            printData();
            Log.d(TAG, "method:initUserConfig#return#newTableVersionCode > lastTableVersionCode");
            return;
        }
        // 降级操作:当前数据库中的数据版本大于最新数据的版本,需要处理新数据
        if (newTableVersionCode < lastTableVersionCode) {
            for (int i = 0; i < newUserConfigList.size(); i++) {
                UserConfigEntity newUserConfig = newUserConfigList.get(i);
                // 该数据的版本号
                int newFieldVersionCode = newUserConfig.getVersion();
                // 该数据的版本号小于上一个版本时,根据操作类型修改,或者删除
                if (newFieldVersionCode < lastTableVersionCode) {
                    //根据数据的操作类型调用相应的修改和删除操作等
                    handleUserConfigByOperationType(newUserConfig);
                }
            }
            // 更新数据库中的版本信息为最新版本
//            if (...) { // 这里可以做一些验证,保证数据库的操作都正确之后再更新这个表的字段
            updateTableVersion(tableVersionEntity.getId(), Constants.TABLE_NAME_USER_CONFIG, newTableVersionCode);
//            }
        }
        printData();
        Log.d(TAG, "method:initUserConfig#newTableVersionCode < lastTableVersionCode");
        Log.d(TAG, "method:initUserConfig#out");
    }

    private void printData() {
        Log.d(TAG, "method:printData#in");
        List<TableVersionEntity> tableVersionList = TableVersionManager.getInstance().queryAllTableVersion();
        Log.d(TAG, "method:printData#tableVersionList=" + tableVersionList);
        long count = UserConfigManager.getInstance().queryCountUserConfig();
        Log.d(TAG, "method:printData#count=" + count);
        List<UserConfigEntity> userConfigList = UserConfigManager.getInstance().queryAllUserConfig();
        Log.d(TAG, "method:printData#userConfigList=" + userConfigList);
        Log.d(TAG, "method:printData#out");
    }


    /**
     * 根据字段的操作类型调用相应的修改、删除等操作
     *
     * @param userConfigEntity
     */
    private long handleUserConfigByOperationType(UserConfigEntity userConfigEntity) {
        Log.d(TAG, "method:handleUserConfiByType#in#arguments:newUserConfig=" + userConfigEntity);
        // 该字段的操作类型
        int operationType = userConfigEntity.getOperationType();
        if (operationType == Constants.USER_CONFIG_FIELD_OPERATION_TYPE_INSERT_OR_UPDATE) {
            long rowId = UserConfigManager.getInstance().insertOrReplaceUserConfig(userConfigEntity);
            Log.d(TAG, "method:handleUserConfiByType#rowId=" + rowId);
            return rowId;
        }
        if (operationType == Constants.USER_CONFIG_FIELD_OPERATION_TYPE_DELETE) {
            String pkey = userConfigEntity.getPkey();
            long removeRowId = UserConfigManager.getInstance().deleteUserConfigByKey(pkey);
            Log.d(TAG, "method:handleUserConfiByType#removeRowId=" + removeRowId);
            return removeRowId;
        }
        Log.d(TAG, "method:handleUserConfiByType#out#return value:0");
        return 0;
    }

    /**
     * 修改本地数据库中表对应的版本号
     *
     * @return
     */
    private void updateTableVersion(long id, String tableName, int versionCode) {
        Log.d(TAG, "method:updateTableVersion#in#arguments:tableName=" + tableName + ", versionCode=" + versionCode);
        TableVersionEntity tableVersion = new TableVersionEntity(id, tableName, versionCode);
        TableVersionManager.getInstance().insertOrReplaceTableVersion(tableVersion);
        Log.d(TAG, "method:updateTableVersion#out");
    }

    /**
     * 解析出json文件中的所有最新的配置相关的数据
     *
     * @return
     */
    public List<UserConfigEntity> parseNewUserConfigList() {
        Log.d(TAG, "method:parseNewUserConfigList#in");
        List<UserConfigEntity> userConfigList = null;
        Map<String, Integer> version = null;
        try {
            String jsonStr = ResUtils.getJsonStr(mContext, "user_config.json");
            Log.d(TAG, "method:parseNewUserConfigList#jsonStr=" + jsonStr);
            Gson gson = new Gson();
            userConfigList = gson.fromJson(jsonStr, new TypeToken<List<UserConfigEntity>>() {
            }.getType());
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.d(TAG, "method:parseNewUserConfigList#out#return value:userConfigList=" + userConfigList);
        return userConfigList;
    }

    /**
     * 解析出json文件中的所有最新的表相关的数据
     *
     * @return
     */
    private Map<String, Integer> parseNewTableVersionMap() {
        Log.d(TAG, "method:parseNewTableVersionMap#in");
        Map<String, Integer> newTableVersionMap = null;
        try {
            String jsonStr = ResUtils.getJsonStr(mContext, "table_version.json");
            Log.d(TAG, "method:parseNewTableVersionMap#jsonStr=" + jsonStr);
            Gson gson = new Gson();
            newTableVersionMap = gson.fromJson(jsonStr, new TypeToken<Map<String, Integer>>() {
            }.getType());
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.d(TAG, "method:parseNewTableVersionMap#out#return value:newTableVersionMap=" + newTableVersionMap);
        return newTableVersionMap;
    }
}

以上是主要的实现过程,对配置数据的修改只需要按照约定改动 json 串文件即可,数据库对应的操作业务一般不需要再作其它修改,示例代码注释写的比较详细,具体的逻辑实现就不再赘述。

GitHub地址

由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!

Hello , World !

感谢所有!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windfallsheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值