处理跨平台差异
- 抽象数据存储接口
- 在Android和iOS开发中,定义一个通用的数据存储接口,例如
DataStorage
接口,包含基本的读写操作,如save(String key, Object value)
和load(String key)
等方法。
- 在Android端实现该接口时,使用
SharedPreferences
进行实际的数据存储操作。例如:
public class AndroidDataStorage implements DataStorage {
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
public AndroidDataStorage(Context context) {
sharedPreferences = context.getSharedPreferences("my_preferences", Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
}
@Override
public void save(String key, Object value) {
if (value instanceof String) {
editor.putString(key, (String) value);
} else if (value instanceof Integer) {
editor.putInt(key, (Integer) value);
}
// 其他数据类型类似处理
editor.apply();
}
@Override
public Object load(String key) {
return sharedPreferences.getAll().get(key);
}
}
- 在iOS端实现该接口时,使用
NSUserDefaults
进行数据存储。例如:
class iOSDataStorage: DataStorage {
let userDefaults = UserDefaults.standard
func save(key: String, value: Any) {
userDefaults.set(value, forKey: key)
userDefaults.synchronize()
}
func load(key: String) -> Any? {
return userDefaults.object(forKey: key)
}
}
- 依赖注入
- 使用依赖注入模式,将
DataStorage
接口的实现类注入到需要数据存储的模块中。例如,在一个业务逻辑类UserManager
中:
// Android端
public class UserManager {
private DataStorage dataStorage;
public UserManager(DataStorage dataStorage) {
this.dataStorage = dataStorage;
}
public void saveUser(User user) {
dataStorage.save("user_name", user.getName());
dataStorage.save("user_age", user.getAge());
}
public User loadUser() {
String name = (String) dataStorage.load("user_name");
int age = (int) dataStorage.load("user_age");
return new User(name, age);
}
}
// iOS端
class UserManager {
let dataStorage: DataStorage
init(dataStorage: DataStorage) {
self.dataStorage = dataStorage
}
func saveUser(user: User) {
dataStorage.save(key: "user_name", value: user.name)
dataStorage.save(key: "user_age", value: user.age)
}
func loadUser() -> User? {
guard let name = dataStorage.load(key: "user_name") as? String,
let age = dataStorage.load(key: "user_age") as? Int else {
return nil
}
return User(name: name, age: age)
}
}
- 这样在不同平台上,可以根据实际情况注入对应的
DataStorage
实现类,从而屏蔽了跨平台差异。
处理多线程和多进程数据一致性问题
- 多线程数据一致性
- 同步锁
- 在Android端,对于
SharedPreferences
的读写操作,可以使用synchronized
关键字进行同步。例如:
private static final Object lock = new Object();
public void saveData(String key, Object value) {
synchronized (lock) {
SharedPreferences.Editor editor = sharedPreferences.edit();
if (value instanceof String) {
editor.putString(key, (String) value);
} else if (value instanceof Integer) {
editor.putInt(key, (Integer) value);
}
editor.apply();
}
}
public Object loadData(String key) {
synchronized (lock) {
return sharedPreferences.getAll().get(key);
}
}
- 在iOS端,使用`DispatchQueue`进行同步。例如:
let queue = DispatchQueue(label: "com.example.dataStorageQueue")
func saveData(key: String, value: Any) {
queue.sync {
UserDefaults.standard.set(value, forKey: key)
UserDefaults.standard.synchronize()
}
}
func loadData(key: String) -> Any? {
var result: Any?
queue.sync {
result = UserDefaults.standard.object(forKey: key)
}
return result
}
- 使用单例模式
- 在Android中,创建一个
SharedPreferences
单例管理类,保证所有对SharedPreferences
的操作都通过这个单例进行,避免多线程同时操作导致的数据不一致。例如:
public class SharedPreferencesSingleton {
private static SharedPreferencesSingleton instance;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
private SharedPreferencesSingleton(Context context) {
sharedPreferences = context.getSharedPreferences("my_preferences", Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
}
public static SharedPreferencesSingleton getInstance(Context context) {
if (instance == null) {
synchronized (SharedPreferencesSingleton.class) {
if (instance == null) {
instance = new SharedPreferencesSingleton(context);
}
}
}
return instance;
}
public void save(String key, Object value) {
synchronized (this) {
if (value instanceof String) {
editor.putString(key, (String) value);
} else if (value instanceof Integer) {
editor.putInt(key, (Integer) value);
}
editor.apply();
}
}
public Object load(String key) {
synchronized (this) {
return sharedPreferences.getAll().get(key);
}
}
}
- 在iOS中,同样可以创建一个`NSUserDefaults`单例管理类。例如:
class UserDefaultsSingleton {
static let shared = UserDefaultsSingleton()
let userDefaults = UserDefaults.standard
private init() {}
func save(key: String, value: Any) {
DispatchQueue.main.sync {
userDefaults.set(value, forKey: key)
userDefaults.synchronize()
}
}
func load(key: String) -> Any? {
var result: Any?
DispatchQueue.main.sync {
result = userDefaults.object(forKey: key)
}
return result
}
}
- 多进程数据一致性
- Android:
- 使用ContentProvider:
- 创建一个
ContentProvider
,通过它来统一管理SharedPreferences
的数据读写。不同进程通过ContentResolver
来访问ContentProvider
。例如:
public class SharedPrefsProvider extends ContentProvider {
private SharedPreferences sharedPreferences;
@Override
public boolean onCreate() {
sharedPreferences = getContext().getSharedPreferences("my_preferences", Context.MODE_MULTI_PROCESS);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
// 实现查询逻辑,例如返回所有数据的Cursor
Map<String,?> all = sharedPreferences.getAll();
MatrixCursor cursor = new MatrixCursor(new String[]{"key", "value"});
for (Map.Entry<String,?> entry : all.entrySet()) {
cursor.addRow(new Object[]{entry.getKey(), entry.getValue()});
}
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SharedPreferences.Editor editor = sharedPreferences.edit();
for (String key : values.keySet()) {
Object value = values.get(key);
if (value instanceof String) {
editor.putString(key, (String) value);
} else if (value instanceof Integer) {
editor.putInt(key, (Integer) value);
}
}
editor.apply();
return uri;
}
// 其他未实现方法需要按需求实现
}
- **监听SharedPreferences变化**:
- 在每个进程中注册`SharedPreferences.OnSharedPreferenceChangeListener`,当`SharedPreferences`数据发生变化时,及时更新本地数据。例如:
SharedPreferences sharedPreferences = getContext().getSharedPreferences("my_preferences", Context.MODE_MULTI_PROCESS);
sharedPreferences.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// 处理数据变化逻辑
Object value = sharedPreferences.getAll().get(key);
// 更新本地UI或其他数据
}
});
- iOS:
- 使用UserDefaults的SuiteName:
- 对于iOS应用的多进程场景(如App Extension),可以使用
UserDefaults
的suiteName
来共享数据。例如:
let sharedUserDefaults = UserDefaults(suiteName: "group.com.example.shared")
sharedUserDefaults?.set("value", forKey: "key")
sharedUserDefaults?.synchronize()
- **使用通知中心**:
- 当数据发生变化时,通过`NSNotificationCenter`发送通知,其他进程监听通知并更新数据。例如:
// 数据变化时发送通知
NotificationCenter.default.post(name: NSNotification.Name("SharedDataChanged"), object: nil, userInfo: ["key": "data_key", "value": "new_value"])
// 监听通知
NotificationCenter.default.addObserver(self, selector: #selector(dataChanged), name: NSNotification.Name("SharedDataChanged"), object: nil)
@objc func dataChanged(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let key = userInfo["key"] as? String,
let value = userInfo["value"] as? String else {
return
}
// 更新本地数据
UserDefaults.standard.set(value, forKey: key)
}