1. Flutter for OpenHarmony 开发环境准备
在开始Flutter for OpenHarmony的文件存储与数据库操作之前,我们需要先搭建好开发环境。OpenHarmony作为新兴的操作系统平台,与传统的Android/iOS开发环境有些许不同。
1.1 基础环境配置
首先需要安装以下工具链:
- Flutter SDK (3.13.0或更高版本)
- OpenHarmony SDK
- DevEco Studio (OpenHarmony官方IDE)
- Java JDK (推荐11或17版本)
配置步骤:
- 下载Flutter SDK并解压到本地目录
- 将Flutter的bin目录添加到系统PATH环境变量
- 安装OpenHarmony SDK时,需要特别注意选择与Flutter兼容的版本
- 配置DevEco Studio时,需要安装Flutter插件和OpenHarmony工具链
注意:OpenHarmony的SDK路径不能包含中文或空格,否则可能导致后续编译失败。
1.2 Flutter for OpenHarmony插件安装
在Flutter项目中,我们需要添加对OpenHarmony平台的支持:
bash复制flutter create --platforms=ohos my_app
cd my_app
flutter pub add flutter_ohos
关键依赖说明:
flutter_ohos: 提供OpenHarmony平台的基础支持path_provider_ohos: OpenHarmony专用的路径获取插件sqflite_ohos: 适配OpenHarmony的SQLite插件
1.3 平台特定配置
在ohos目录下的config.json中,需要添加文件存储和数据库权限:
json复制{
"module": {
"reqPermissions": [
{
"name": "ohos.permission.FILE_ACCESS",
"reason": "需要访问应用文件目录"
},
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC",
"reason": "需要数据库同步能力"
}
]
}
}
2. OpenHarmony文件系统操作详解
2.1 OpenHarmony文件系统特性
OpenHarmony的文件系统与Android有显著差异,主要特点包括:
- 严格的沙箱机制:应用只能访问指定目录
- 分布式文件系统:支持跨设备文件访问
- 安全分级:不同安全级别的数据存储在不同目录
2.2 路径获取与管理
在OpenHarmony中,我们需要使用专门适配的path_provider_ohos插件:
dart复制import 'package:path_provider_ohos/path_provider_ohos.dart';
class OhosPathManager {
/// 获取应用私有目录
/// 路径示例:/data/storage/el2/base/haps/entry/files
static Future<String> getAppDataPath() async {
final dir = await getApplicationSupportDirectory();
return dir.path;
}
/// 获取临时目录
/// 路径示例:/data/storage/el2/base/haps/entry/temp
static Future<String> getTempPath() async {
final dir = await getTemporaryDirectory();
return dir.path;
}
/// 获取外部共享目录
/// 需要ohos.permission.FILE_ACCESS权限
static Future<String?> getExternalStoragePath() async {
try {
final dir = await getExternalStorageDirectory();
return dir?.path;
} catch (e) {
print('获取外部存储失败: $e');
return null;
}
}
}
2.3 文件操作最佳实践
针对OpenHarmony平台的文件操作,我们需要注意以下要点:
- 跨设备文件访问:
dart复制Future<void> syncFileToDevice(String filePath, String deviceId) async {
final file = File(filePath);
if (await file.exists()) {
// 使用OpenHarmony的分布式能力同步文件
final result = await OhosDistributedFileManager.syncFile(
localPath: filePath,
targetDevice: deviceId,
);
if (!result) {
throw Exception('文件同步失败');
}
}
}
- 大文件分块处理:
dart复制Future<void> processLargeFile(String filePath) async {
const chunkSize = 1024 * 1024; // 1MB
final file = File(filePath);
final fileSize = await file.length();
for (var i = 0; i < fileSize; i += chunkSize) {
final chunk = await file.readAsBytes(
start: i,
end: i + chunkSize > fileSize ? fileSize : i + chunkSize,
);
// 处理文件块...
}
}
- 文件加密存储:
dart复制Future<void> saveEncryptedFile(String path, String content) async {
final encrypted = OhosCrypto.encrypt(content);
await File(path).writeAsString(encrypted);
}
Future<String> readEncryptedFile(String path) async {
final content = await File(path).readAsString();
return OhosCrypto.decrypt(content);
}
3. SQLite数据库在OpenHarmony中的实践
3.1 OpenHarmony数据库特性
OpenHarmony的数据库系统具有以下特点:
- 支持分布式数据库:数据可跨设备同步
- 增强的安全机制:支持数据加密
- 优化的性能:针对嵌入式设备做了特别优化
3.2 数据库初始化与配置
使用sqflite_ohos插件进行数据库操作:
dart复制import 'package:sqflite_ohos/sqflite_ohos.dart';
class OhosDatabaseHelper {
static const _dbName = 'app_database.db';
static const _dbVersion = 1;
static Database? _database;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}
Future<Database> _initDatabase() async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, _dbName);
return await openDatabase(
path,
version: _dbVersion,
onCreate: _onCreate,
onConfigure: (db) async {
// 启用分布式同步
await db.execute('PRAGMA distributed_sync=ON');
// 启用加密
await db.execute('PRAGMA key="your_encryption_key"');
},
);
}
Future<void> _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
distributed_id TEXT, // 分布式ID
sync_status INTEGER DEFAULT 0
)
''');
}
}
3.3 分布式数据库操作
OpenHarmony的分布式数据库能力是其核心特色:
dart复制class DistributedDbManager {
final DatabaseHelper _dbHelper = DatabaseHelper();
/// 标记数据需要同步
Future<void> markForSync(int id) async {
final db = await _dbHelper.database;
await db.update(
'users',
{'sync_status': 1},
where: 'id = ?',
whereArgs: [id],
);
}
/// 获取待同步数据
Future<List<Map<String, dynamic>>> getPendingSyncData() async {
final db = await _dbHelper.database;
return await db.query(
'users',
where: 'sync_status = ?',
whereArgs: [1],
);
}
/// 同步数据到其他设备
Future<void> syncData(String deviceId) async {
final pendingData = await getPendingSyncData();
final result = await OhosDistributedDb.sync(
table: 'users',
data: pendingData,
targetDevice: deviceId,
);
if (result) {
final db = await _dbHelper.database;
final ids = pendingData.map((e) => e['id']).join(',');
await db.rawUpdate('''
UPDATE users SET sync_status = 0
WHERE id IN ($ids)
''');
}
}
}
4. 性能优化与安全实践
4.1 数据库性能优化
针对OpenHarmony平台的数据库优化策略:
- 索引优化:
dart复制Future<void> createIndexes() async {
final db = await database;
await db.execute('''
CREATE INDEX idx_users_email ON users(email)
''');
await db.execute('''
CREATE INDEX idx_users_sync ON users(sync_status)
''');
}
- 批量操作优化:
dart复制Future<void> batchInsertUsers(List<User> users) async {
final db = await database;
final batch = db.batch();
for (final user in users) {
batch.insert('users', user.toMap());
}
await batch.commit(noResult: true);
// 触发增量同步
await _syncIncrementalData();
}
- 查询优化:
dart复制Future<List<User>> queryUsers(int page, int pageSize) async {
final db = await database;
final offset = (page - 1) * pageSize;
return await db.transaction((txn) async {
final results = await txn.query(
'users',
columns: ['id', 'name', 'email'],
limit: pageSize,
offset: offset,
orderBy: 'name ASC',
);
return results.map((map) => User.fromMap(map)).toList();
});
}
4.2 安全实践
- 数据加密:
dart复制Future<Database> openEncryptedDatabase() async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, 'secure_data.db');
return await openDatabase(
path,
password: 'your_strong_password',
options: OpenDatabaseOptions(
version: 1,
onCreate: (db, version) async {
// 初始化加密数据库
await db.execute('PRAGMA cipher_default_kdf_iter = 64000');
await db.execute('PRAGMA cipher_default_page_size = 4096');
// 创建表...
},
),
);
}
- 安全删除:
dart复制Future<void> secureDeleteDatabase() async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, 'secure_data.db');
// 先覆盖文件内容
final file = File(path);
if (await file.exists()) {
final length = await file.length();
await file.writeAsBytes(List.filled(length, 0));
}
// 再删除文件
await deleteDatabase(path);
}
- 权限检查:
dart复制Future<bool> checkFilePermission() async {
try {
final status = await OhosPermission.check(
'ohos.permission.FILE_ACCESS'
);
return status == PermissionStatus.granted;
} catch (e) {
return false;
}
}
5. 实战案例:跨设备待办事项应用
5.1 应用架构设计
我们设计一个支持跨设备同步的待办事项应用:
code复制lib/
├── models/
│ ├── todo.dart # 数据模型
│ └── user.dart
├── services/
│ ├── db_service.dart # 数据库服务
│ └── sync_service.dart # 同步服务
└── utils/
├── file_utils.dart # 文件工具
└── crypto_utils.dart # 加密工具
5.2 核心实现代码
数据库服务实现:
dart复制class TodoDbService {
static const _tableName = 'todos';
Future<Database> get _db async {
return await OhosDatabaseHelper().database;
}
Future<int> createTodo(Todo todo) async {
final db = await _db;
final id = await db.insert(_tableName, todo.toMap());
// 标记需要同步
await db.update(
_tableName,
{'sync_status': 1},
where: 'id = ?',
whereArgs: [id],
);
return id;
}
Future<List<Todo>> getTodos({bool onlyPending = false}) async {
final db = await _db;
final where = onlyPending ? 'sync_status = ?' : null;
final whereArgs = onlyPending ? [1] : null;
final maps = await db.query(
_tableName,
where: where,
whereArgs: whereArgs,
);
return maps.map(Todo.fromMap).toList();
}
}
文件附件服务:
dart复制class TodoAttachmentService {
static Future<String> saveAttachment(File file) async {
final dir = await getApplicationDocumentsDirectory();
final attachmentsDir = Directory('${dir.path}/attachments');
if (!await attachmentsDir.exists()) {
await attachmentsDir.create(recursive: true);
}
final timestamp = DateTime.now().millisecondsSinceEpoch;
final extension = p.extension(file.path);
final newPath = '${attachmentsDir.path}/$timestamp$extension';
await file.copy(newPath);
return newPath;
}
static Future<void> syncAttachment(String filePath, String deviceId) async {
await OhosDistributedFileManager.syncFile(
localPath: filePath,
targetDevice: deviceId,
);
}
}
5.3 同步策略实现
dart复制class TodoSyncService {
final _dbService = TodoDbService();
final _fileService = TodoAttachmentService();
Future<void> syncWithDevice(String deviceId) async {
// 同步待办事项
final pendingTodos = await _dbService.getTodos(onlyPending: true);
await _syncTodos(pendingTodos, deviceId);
// 同步附件
await _syncAttachments(pendingTodos, deviceId);
}
Future<void> _syncTodos(List<Todo> todos, String deviceId) async {
final db = await OhosDatabaseHelper().database;
final batch = db.batch();
for (final todo in todos) {
// 分配分布式ID
if (todo.distributedId == null) {
todo.distributedId = const Uuid().v4();
batch.update(
'todos',
{'distributed_id': todo.distributedId},
where: 'id = ?',
whereArgs: [todo.id],
);
}
// 同步到目标设备
await OhosDistributedDb.insert(
deviceId: deviceId,
table: 'todos',
data: todo.toMap(),
);
// 标记为已同步
batch.update(
'todos',
{'sync_status': 0},
where: 'id = ?',
whereArgs: [todo.id],
);
}
await batch.commit();
}
Future<void> _syncAttachments(List<Todo> todos, String deviceId) async {
for (final todo in todos) {
if (todo.attachmentPath != null) {
await _fileService.syncAttachment(todo.attachmentPath!, deviceId);
}
}
}
}
6. 调试与问题排查
6.1 常见问题解决方案
- 数据库无法创建问题:
- 检查应用是否有存储权限
- 确认数据库路径不包含特殊字符
- 查看OpenHarmony系统日志:
hilog | grep Database
- 文件同步失败问题:
- 确认设备已连接到同一网络
- 检查分布式能力是否开启
- 验证设备间信任关系是否建立
- 性能优化建议:
dart复制// 不好的写法
for (var i = 0; i < 1000; i++) {
await db.insert('items', {'value': i});
}
// 好的写法 - 使用事务
await db.transaction((txn) async {
final batch = txn.batch();
for (var i = 0; i < 1000; i++) {
batch.insert('items', {'value': i});
}
await batch.commit();
});
6.2 调试工具推荐
- OpenHarmony DevEco Debugger:
- 实时查看数据库内容
- 监控文件系统变化
- 跟踪分布式同步状态
- 数据库探查工具:
bash复制# 导出数据库内容
hdc shell "cp /data/app/el2/100/base/com.example.app/databases/app.db /sdcard/"
hdc file recv /sdcard/app.db ./app.db
# 使用DB Browser for SQLite查看
- 性能分析工具:
dart复制void main() {
// 启用SQL性能日志
debugPrint = (String? message, {int? wrapWidth}) {
if (message?.startsWith('SQL') ?? false) {
OhosLogger.sql(message!);
}
};
runApp(MyApp());
}
7. 进阶主题
7.1 自定义文件存储引擎
对于特殊需求,可以实现自定义文件存储引擎:
dart复制abstract class FileStorageEngine {
Future<void> write(String path, List<int> bytes);
Future<List<int>> read(String path);
Future<bool> exists(String path);
Future<void> delete(String path);
}
class OhosSecureFileStorage implements FileStorageEngine {
@override
Future<void> write(String path, List<int> bytes) async {
final encrypted = OhosCrypto.encryptBytes(bytes);
await File(path).writeAsBytes(encrypted);
}
@override
Future<List<int>> read(String path) async {
final bytes = await File(path).readAsBytes();
return OhosCrypto.decryptBytes(bytes);
}
// 其他方法实现...
}
7.2 数据库迁移策略
处理复杂的数据迁移场景:
dart复制class MigrationHelper {
static const migrations = {
2: _migrateV1ToV2,
3: _migrateV2ToV3,
};
static Future<void> _migrateV1ToV2(Database db) async {
await db.execute('ALTER TABLE users ADD COLUMN phone TEXT');
// 迁移现有数据...
}
static Future<void> _migrateV2ToV3(Database db) async {
await db.execute('CREATE TABLE new_users (id INTEGER, name TEXT, ...)');
// 复杂的数据转换...
await db.execute('DROP TABLE users');
await db.execute('ALTER TABLE new_users RENAME TO users');
}
static Future<void> runMigrations(Database db, int oldVersion, int newVersion) async {
for (var version = oldVersion + 1; version <= newVersion; version++) {
if (migrations.containsKey(version)) {
await migrations[version]!(db);
}
}
}
}
7.3 与HarmonyOS生态集成
如何与HarmonyOS的其他能力结合:
dart复制class HarmonyOsIntegration {
/// 使用Ability访问系统服务
static Future<void> saveToSystemGallery(String filePath) async {
final ability = await OhosAbility.connect(
'ohos.ability.gallery',
);
await ability.call(
'saveImage',
{'path': filePath},
);
}
/// 使用Intent打开文件
static Future<void> openFile(String path) async {
await OhosIntent.openFile(
uri: Uri.file(path),
mimeType: _getMimeType(path),
);
}
}
在实际开发中,我发现OpenHarmony平台的文件和数据库操作虽然基础概念与其他平台相似,但在分布式能力、安全机制和性能优化方面有独特的设计。特别是在处理跨设备数据同步时,需要考虑网络状态、冲突解决等复杂场景。建议在开发前充分了解OpenHarmony的分布式设计理念,这将帮助开发者更好地利用平台特性,构建更强大的应用。
