面试题答案
一键面试保证数据存储格式和访问权限一致性
- 使用统一的接口抽象:在Flutter中,可以创建一个抽象类来封装SharedPreferences的操作,针对不同平台实现具体的操作类。例如:
abstract class SharedPreferencesHelper {
Future<void> setString(String key, String value);
Future<String?> getString(String key);
// 其他类似的方法
}
class AndroidSharedPreferencesHelper implements SharedPreferencesHelper {
@override
Future<void> setString(String key, String value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(key, value);
}
@override
Future<String?> getString(String key) async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(key);
}
}
class IOSSharedPreferencesHelper implements SharedPreferencesHelper {
// 类似的实现,在iOS上可能需要使用不同的存储方式,但接口保持一致
}
- 数据格式标准化:在存储数据时,尽量使用通用的数据格式。例如,对于复杂数据结构,使用JSON进行序列化和反序列化。
class User {
final String name;
final int age;
User(this.name, this.age);
Map<String, dynamic> toJson() => {
'name': name,
'age': age
};
factory User.fromJson(Map<String, dynamic> json) => User(
json['name'],
json['age']
);
}
// 存储
Future<void> saveUser(User user) async {
final helper = getSharedPreferencesHelper(); // 获取对应平台的helper
final json = user.toJson();
await helper.setString('user', jsonEncode(json));
}
// 读取
Future<User?> loadUser() async {
final helper = getSharedPreferencesHelper();
final jsonStr = await helper.getString('user');
if (jsonStr != null) {
final json = jsonDecode(jsonStr);
return User.fromJson(json);
}
return null;
}
- 访问权限管理:
- 在Android中,确保在
AndroidManifest.xml
中配置适当的权限,例如:
- 在Android中,确保在
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- 在iOS中,在
Info.plist
中配置相应的权限说明,例如:
<key>NSUserDefaultsRequiresAsynchronousAccess</key>
<true/>
同时,在Flutter代码中,通过上述抽象接口来访问数据,避免直接在不同平台的特定代码中处理权限,以保持一致性。
确保存储数据的安全性,防止数据泄露
- 数据加密:在存储数据前对敏感数据进行加密。可以使用
encrypt
库进行加密。
import 'package:encrypt/encrypt.dart';
final key = Key.fromLength(32);
final iv = IV.fromLength(16);
final encrypter = Encrypter(AES(key));
// 加密数据
Future<void> saveEncryptedString(String key, String value) async {
final encrypted = encrypter.encrypt(value, iv: iv);
final helper = getSharedPreferencesHelper();
await helper.setString(key, encrypted.base64);
}
// 解密数据
Future<String?> loadDecryptedString(String key) async {
final helper = getSharedPreferencesHelper();
final encryptedStr = await helper.getString(key);
if (encryptedStr != null) {
final encrypted = Encrypted.fromBase64(encryptedStr);
return encrypter.decrypt(encrypted, iv: iv);
}
return null;
}
- 限制访问范围:
- 仅在必要的地方访问SharedPreferences数据,避免在多个不必要的地方获取数据。
- 在应用的架构设计上,将SharedPreferences的访问逻辑集中在少数几个模块中,便于管理和控制访问权限。
- 应用加固:
- 在Android上,可以使用ProGuard或R8进行代码混淆,防止反编译获取数据访问逻辑。
- 在iOS上,启用App Thinning和Bitcode,并且确保应用在发布前进行了安全扫描。