Android Java项目中Preferences DataStore实现及迁移求助
一、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
相关产品推荐
相关产品推荐

