Android下载SQLite数据库后无法访问Foods表问题求助
问题解决:Android中访问下载的SQLite数据库提示表不存在
核心原因
Amplify的downloadFile是异步操作,你当前的代码在调用下载后立刻尝试访问数据库,此时文件可能还未完成下载,导致打开的是不完整/空的数据库文件,自然找不到Foods表。此外,原代码中还有几处容易引发异常的问题。
修复步骤及代码示例
1. 确保数据库下载完成后再操作
将数据库访问逻辑移到下载成功的回调中,保证操作的是完整的数据库文件:
String filekey = mobile + ".db"; File file = new File(getApplicationContext().getFilesDir(), filekey); // 更安全的路径拼接方式 Amplify.Storage.downloadFile( filekey, file, result -> { Log.i("Myamplifyapp", "文件下载完成:" + result.getFile().getName()); // 下载成功后才执行数据库操作 handleDatabaseQuery(file.getAbsolutePath()); }, error -> { Log.e("Myamplifyapp", "文件下载失败", error); Toast.makeText(userOtpActivity.this, "数据库下载失败", Toast.LENGTH_SHORT).show(); } );
2. 安全的数据库查询逻辑
单独封装数据库查询方法,修正原代码中的潜在异常点:
private void handleDatabaseQuery(String dbPath) { SQLiteDatabase db = null; Cursor foods_cursor = null; try { // 仅需只读权限,避免不必要的写操作 db = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY); String[] cols = {"Date_Time", "Food", "Calories"}; foods_cursor = db.query("Foods", cols, null, null, null, null, null); ArrayList<String> date_Time = new ArrayList<>(); ArrayList<String> food_item = new ArrayList<>(); ArrayList<String> calories = new ArrayList<>(); int i = 0; // 先判断游标是否有数据,再读取 if (foods_cursor.moveToFirst()) { do { // 使用getColumnIndex避免列顺序变化导致的错误 date_Time.add(foods_cursor.getString(foods_cursor.getColumnIndex("Date_Time"))); food_item.add(foods_cursor.getString(foods_cursor.getColumnIndex("Food"))); calories.add(foods_cursor.getString(foods_cursor.getColumnIndex("Calories"))); i++; } while (foods_cursor.moveToNext() && i < 600); } // 按需处理数据,比如显示第一条食物名称 if (!food_item.isEmpty()) { Toast.makeText(this, "第一条记录:" + food_item.get(0), Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "数据库中无数据", Toast.LENGTH_SHORT).show(); } } catch (SQLiteException e) { Log.e("DB_ERROR", "数据库访问失败", e); Toast.makeText(this, "错误:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } finally { // 确保游标和数据库关闭,避免资源泄漏 if (foods_cursor != null) foods_cursor.close(); if (db != null) db.close(); } }
3. 其他注意事项
- 原代码中在
moveToFirst()之前就调用foods_cursor.getString(1),会直接抛出异常,必须先确认游标指向有效数据再读取。 - 避免在UI线程执行耗时的数据库查询,可使用
Coroutine或AsyncTask将操作移到子线程,防止界面卡顿。 - 路径拼接建议使用
File类的构造方法,避免手动拼接字符串出现错误。
内容的提问来源于stack exchange,提问作者Rajendiran S
相关产品推荐
相关产品推荐

