从assets复制的SQLite数据库无表,硬编码路径可用但不兼容多设备
问题根因
你的路径获取逻辑存在明确错误:
context.getDatabasePath(dbName)方法返回的就是指向questions.db的完整文件对象,本身已经包含了数据库文件名,你后续再次拼接questions.db会导致路径重复。例如正确路径是/data/data/你的应用包名/databases/questions.db,拼接后变成了错误的/data/data/你的应用包名/databases/questions.dbquestions.db,路径完全不存在,因此dbFile.exists()判断逻辑完全不符合预期。- 你调用
super.getWritableDatabase()时,系统会自动生成一个没有表的空questions.db文件,复制操作实际覆盖的是这个系统生成的空库路径,但你判断存在性的是拼接错误的路径,所以每次调用都会重复生成空库,自然找不到assets里预置的表。
修复方案
1. 修正构造方法的路径初始化逻辑
public DatabaseAssets(Context context) { super(context, "questions.db", null, 1); this.context = context; // 直接使用getDatabasePath返回的文件,无需额外拼接文件名 dbFile = context.getDatabasePath(dbName); }
2. 修正数据库获取方法的返回逻辑
@Override public synchronized SQLiteDatabase getWritableDatabase() { if(!dbFile.exists()){ SQLiteDatabase db = super.getWritableDatabase(); copyDataBase(db.getPath()); // 关闭父类生成的空库,避免文件占用 db.close(); } // 直接打开已经写入assets数据的数据库文件 return SQLiteDatabase.openDatabase(dbFile.getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE); } @Override public synchronized SQLiteDatabase getReadableDatabase() { if(!dbFile.exists()){ SQLiteDatabase db = super.getReadableDatabase(); copyDataBase(db.getPath()); db.close(); } return SQLiteDatabase.openDatabase(dbFile.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY); }
3. 其他校验点
- 确认assets目录下确实存在
databases/questions.db文件,路径、大小写完全匹配 - 你复制代码里的变量名
assestDB拼写错误,若实际路径是照着变量名敲的需要修正为assets - 应用升级时建议先删除旧数据库文件,避免残留数据异常
内容的提问来源于stack exchange,提问作者ChaChaCha
相关产品推荐
相关产品推荐

