Android 10环境下React Native应用二次启动TypeORM数据库同步异常
问题描述
开发基于React Native + Expo的应用,采用TypeORM管理本地数据存储。仅Android 10的模拟器/真机出现异常:首次启动数据库初始化正常,但重载应用或杀死进程后再次启动,会触发数据库表创建与同步失败的错误。Android 11、12测试无此问题。
使用的依赖版本:
"react": "18.1.0", "react-native": "0.70.5", "reflect-metadata": "^0.1.13", "ts-node-dev": "^2.0.0", "expo-sqlite": "^11.0.0", "typeorm": "^0.3.12",
排查与解决方案
1. 适配Android 10分区存储权限
Android 10的分区存储机制可能导致二次启动时数据库文件访问权限不足。
- 在
app.json中添加权限配置并关闭分区存储强制适配:"android": { "permissions": ["READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"], "scopedStorage": false } - 确保TypeORM使用Expo SQLite提供的默认数据库实例,避免自定义路径:
import { openDatabase } from 'expo-sqlite'; import { DataSource } from 'typeorm'; const dbInstance = openDatabase('app-db.db'); const AppDataSource = new DataSource({ type: 'expo', database: dbInstance, entities: [/* 你的实体类 */], synchronize: true, logging: false, });
2. 修复数据库连接未释放的资源锁定问题
重载/重启时未关闭旧连接,导致Android 10下SQLite文件被锁定。
- 在应用后台/终止时手动销毁数据源:
import { AppState } from 'react-native'; AppState.addEventListener('change', async (state) => { if (state === 'background' && AppDataSource.isInitialized) { await AppDataSource.destroy(); } }); - 初始化前检查数据源状态,已初始化则先销毁再重建:
export async function initDB() { if (AppDataSource.isInitialized) { await AppDataSource.destroy(); } await AppDataSource.initialize(); }
3. 调整依赖版本兼容性
expo-sqlite@11.0.0与Android 10的SQLite驱动可能存在适配问题。
- 降级
expo-sqlite到稳定兼容版本:npm install expo-sqlite@10.2.0 - 同步升级TypeORM至官方推荐的适配版本,参考TypeORM文档确认版本匹配关系。
4. 替换自动同步为迁移机制
synchronize: true在Android 10下易因文件锁导致同步失败,改用迁移管理表结构。
- 修改TypeORM配置关闭自动同步,启用迁移:
const AppDataSource = new DataSource({ // ...其他配置 synchronize: false, migrations: [require('./migrations/*.ts')], migrationsTableName: 'db_migrations', }); - 初始化时手动执行迁移:
await AppDataSource.initialize(); await AppDataSource.runMigrations();
内容的提问来源于stack exchange,提问作者WerllenTrindade
相关产品推荐
相关产品推荐

