You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:15:43