Android MMKV 接入+ 替换原生 SP + 原生 SP 数据迁移

背景:项目中一直使用的是原生 SP,众所周知,使用原生 SP 存在卡顿性能问题。公司的性能监控平台抓到不少原生 SP 导致的 ANR 问题:


java.io.FileDescriptor.sync (FileDescriptor.java)
android.os.FileUtils.sync (FileUtils.java:256)
android.app.SharedPreferencesImpl.writeToFile (SharedPreferencesImpl.java:807)
android.app.SharedPreferencesImpl.access$900 (SharedPreferencesImpl.java:59)
android.app.SharedPreferencesImpl$2.run (SharedPreferencesImpl.java:672)
android.app.QueuedWork.processPendingWork (QueuedWork.java:265)
android.app.QueuedWork.waitToFinish (QueuedWork.java:178)
android.app.ActivityThread.handleServiceArgs (ActivityThread.java:4977)
android.app.ActivityThread.access$2300 (ActivityThread.java:284)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:2322)
android.os.Handler.dispatchMessage (Handler.java:106)
android.os.Looper.loopOnce (Looper.java:233)
android.os.Looper.loop (Looper.java:334)
android.app.ActivityThread.main (ActivityThread.java:8396)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:582)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1068)

因此,替换原生 SP 迫在眉睫。

本文记录如何使用腾讯开源框架 MMKV 替换原生 SP、以及替换后当中遇到的一些问题解决。

一、替换方案选择

综合考虑,我们选择了方案3

二、接入 MMKV

  1. 新建 MMKV module

build.gradle 中添加依赖,这里采用的是较为稳定的版本 1.2.14

implementation 'com.tencent:mmkv:1.2.14'

2. 重新实现SharedPreferences.Editor, SharedPreferences 以及迁移原本的 SharePreferences 数据


package com.mikel.mmkv;

import android.content.Context;
import android.content.SharedPreferences;

import com.tencent.mmkv.MMKV;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class MMKVSP implements SharedPreferences.Editor, SharedPreferences {

    private MMKV mmkv;
    private Context mContext;
    private boolean isMultiprocess;
    private ArrayList<OnSharedPreferenceChangeListener> listeners;
    private final Object listenerLock = new Object();
    public static void initialize(Context context) {
         MMKV.initialize(context);
    }

    public MMKVSP(Context context, String name, boolean multiProcess) {
        mContext = context;
        isMultiprocess = multiProcess;
        mmkv = MMKV.mmkvWithID(name,
                (isMultiprocess? Context.MODE_MULTI_PROCESS :  Context.MODE_PRIVATE));
        listeners = new ArrayList<>();
        importFromAndroidSp(name);
    }

    private void importFromAndroidSp(String fileName) {
        MMKV migrateSpRecord = MMKV.mmkvWithID("migrate_sp_record");
        boolean isImported = migrateSpRecord.getBoolean(fileName, false);
        SharedPreferences sharedPreferences = null;
        if (!isImported) {
            if(mContext instanceof IMMKVProvider) {
                sharedPreferences = ((IMMKVProvider)mContext).getSuperSharedPreferences(fileN

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-19 17:28:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-19 17:28:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-19 17:28:02       87 阅读
  4. Python语言-面向对象

    2024-02-19 17:28:02       96 阅读

热门阅读

  1. 二级 C 语言笔试-15

    2024-02-19 17:28:02       41 阅读
  2. 【vue】组件通信方式介绍

    2024-02-19 17:28:02       52 阅读
  3. 从零实现softmax回归【基于Pytorch】

    2024-02-19 17:28:02       55 阅读
  4. 使用docker搭建php开发环境

    2024-02-19 17:28:02       66 阅读
  5. 怎么测试阿里云香港服务器是不是cn2?

    2024-02-19 17:28:02       56 阅读
  6. C/C++与汇编交互总结

    2024-02-19 17:28:02       50 阅读
  7. (力扣记录)199.二叉树的右视图

    2024-02-19 17:28:02       45 阅读