You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Java项目中Preferences DataStore实现及迁移求助

Java实现Preferences DataStore及从SharedPreferences迁移示例

一、Preferences DataStore 基础Java实现

1. 添加依赖

在Module级别的build.gradle中引入必要依赖:

dependencies {
    // Preferences DataStore核心库
    implementation "androidx.datastore:datastore-preferences:1.0.0"
    // RxJava依赖(适配Java异步操作)
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
}

2. 创建DataStore单例管理类

确保全局只有一个DataStore实例,避免资源浪费:

import android.content.Context;
import androidx.datastore.preferences.core.Preferences;
import androidx.datastore.preferences.core.PreferencesKeys;
import androidx.datastore.preferences.rxjava3.RxPreferenceDataStoreBuilder;
import androidx.datastore.rxjava3.RxDataStore;

public class DataStoreManager {
    private static volatile RxDataStore<Preferences> INSTANCE;

    // 定义存储键(统一管理避免拼写错误)
    public static final PreferencesKeys.StringKey USER_NAME = PreferencesKeys.stringKey("user_name");
    public static final PreferencesKeys.IntKey USER_AGE = PreferencesKeys.intKey("user_age");
    public static final PreferencesKeys.BooleanKey IS_LOGGED_IN = PreferencesKeys.booleanKey("is_logged_in");

    private DataStoreManager() {}

    public static RxDataStore<Preferences> getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (DataStoreManager.class) {
                if (INSTANCE == null) {
                    INSTANCE = new RxPreferenceDataStoreBuilder(
                            context.getApplicationContext(), "app_preferences")
                            .build();
                }
            }
        }
        return INSTANCE;
    }
}

3. 写入数据示例

import androidx.datastore.preferences.core.Preferences;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;

public void saveUserData(String name, int age, boolean isLoggedIn) {
    DataStoreManager.getInstance(context)
            .updateDataAsync(prefsIn -> {
                Preferences.MutablePreferences mutablePrefs = prefsIn.toMutablePreferences();
                mutablePrefs.set(DataStoreManager.USER_NAME, name);
                mutablePrefs.set(DataStoreManager.USER_AGE, age);
                mutablePrefs.set(DataStoreManager.IS_LOGGED_IN, isLoggedIn);
                return kotlin.coroutines.ContinuationKt.returnValue(mutablePrefs);
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                    () -> { /* 写入成功后的逻辑,如更新UI或提示 */ },
                    throwable -> { /* 写入失败处理,比如Toast提示错误 */ }
            );
}

4. 读取数据示例

import androidx.datastore.preferences.core.Preferences;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;

public void loadUserData() {
    DataStoreManager.getInstance(context)
            .data()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                    prefs -> {
                        String userName = prefs.get(DataStoreManager.USER_NAME) != null ? prefs.get(DataStoreManager.USER_NAME) : "";
                        int userAge = prefs.get(DataStoreManager.USER_AGE) != null ? prefs.get(DataStoreManager.USER_AGE) : 0;
                        boolean isLoggedIn = prefs.get(DataStoreManager.IS_LOGGED_IN) != null ? prefs.get(DataStoreManager.IS_LOGGED_IN) : false;
                        // 用读取到的数据更新UI或业务逻辑
                    },
                    throwable -> { /* 读取失败处理 */ }
            );
}

二、从SharedPreferences迁移至Preferences DataStore

1. 编写迁移逻辑

创建迁移回调,将SharedPreferences的旧数据复制到DataStore:

import android.content.Context;
import androidx.datastore.preferences.core.Preferences;
import androidx.datastore.preferences.core.PreferencesKeys;
import androidx.datastore.preferences.rxjava3.RxPreferenceDataStoreBuilder;
import androidx.datastore.rxjava3.RxDataStore;
import androidx.preference.PreferenceManager;

public class DataStoreMigration {

    public static RxDataStore<Preferences> getMigratedDataStore(Context context) {
        return new RxPreferenceDataStoreBuilder(
                context.getApplicationContext(), "app_preferences")
                .setMigrationCallbacks(new RxPreferenceDataStoreBuilder.MigrationCallbacks() {
                    @Override
                    public void onMigrate(Preferences.MutablePreferences mutablePreferences) {
                        // 获取旧的SharedPreferences实例
                        android.content.SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
                        
                        // 逐个迁移键值对(根据你的实际存储键调整)
                        if (sharedPrefs.contains("user_name")) {
                            String userName = sharedPrefs.getString("user_name", "");
                            mutablePreferences.set(PreferencesKeys.stringKey("user_name"), userName);
                        }
                        if (sharedPrefs.contains("user_age")) {
                            int userAge = sharedPrefs.getInt("user_age", 0);
                            mutablePreferences.set(PreferencesKeys.intKey("user_age"), userAge);
                        }
                        if (sharedPrefs.contains("is_logged_in")) {
                            boolean isLoggedIn = sharedPrefs.getBoolean("is_logged_in", false);
                            mutablePreferences.set(PreferencesKeys.booleanKey("is_logged_in"), isLoggedIn);
                        }

                        // 迁移完成后可清除SharedPreferences数据(可选,避免冗余)
                        sharedPrefs.edit().clear().apply();
                    }
                })
                .build();
    }
}

2. 更新DataStore单例

修改DataStoreManager的实例初始化逻辑,使用迁移后的DataStore:

public class DataStoreManager {
    private static volatile RxDataStore<Preferences> INSTANCE;

    // 存储键定义不变
    public static final PreferencesKeys.StringKey USER_NAME = PreferencesKeys.stringKey("user_name");
    public static final PreferencesKeys.IntKey USER_AGE = PreferencesKeys.intKey("user_age");
    public static final PreferencesKeys.BooleanKey IS_LOGGED_IN = PreferencesKeys.booleanKey("is_logged_in");

    private DataStoreManager() {}

    public static RxDataStore<Preferences> getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (DataStoreManager.class) {
                if (INSTANCE == null) {
                    // 使用迁移后的DataStore实例
                    INSTANCE = DataStoreMigration.getMigratedDataStore(context);
                }
            }
        }
        return INSTANCE;
    }
}

3. 迁移注意事项

  • 迁移仅在DataStore首次创建时执行一次,后续不会重复触发。
  • 迁移过程在后台线程执行,不会阻塞主线程。
  • 若不需要保留旧数据,迁移完成后建议清除SharedPreferences内容。

内容的提问来源于stack exchange,提问作者ChanduGudimetla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:30:46