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

Udacity热门电影项目:SQLite数据无法持久化问题求助

排查收藏数据无法持久化的常见问题

从你描述的情况来看,应用重启后收藏数据丢失,大概率是数据没有真正写入到SQLite数据库(毕竟Content Provider底层通常依赖SQLite),或者读取数据的逻辑存在疏漏。下面是几个最容易踩坑的点,你可以逐一排查:

1. 收藏操作时是否正确调用了ContentResolver的写入方法?

很多开发者会误以为调用了Content Provider的方法就完成了存储,但如果你的insert/update实现有问题,数据根本没落地:

  • 有没有在Content Provider的insert方法里真正执行SQLiteDatabase.insert(),并且返回了正确的Uri?如果返回null,说明插入失败;
  • 传递的ContentValues是不是为空,或者字段名和数据库表的列名不匹配?比如表列叫movie_title,你却存了title,数据自然写不进去;
  • 是不是直接操作了SQLite数据库,但没通过getContentResolver().insert(...)走Content Provider的流程?这样数据不会被Content Provider感知,后续读取也可能出问题。

给你贴个正确的收藏写入示例:

// 收藏影片时的核心代码
ContentValues values = new ContentValues();
values.put(MovieContract.MovieEntry.COLUMN_MOVIE_ID, movie.getId());
values.put(MovieContract.MovieEntry.COLUMN_TITLE, movie.getTitle());
values.put(MovieContract.MovieEntry.COLUMN_POSTER_PATH, movie.getPosterPath());
// 其他必填字段...

Uri insertedUri = getContentResolver().insert(MovieContract.MovieEntry.CONTENT_URI, values);
// 可以通过Uri是否为null判断写入是否成功
if (insertedUri == null) {
    // 这里可以加个日志,确认写入失败了
    Log.e("MainActivity", "收藏影片失败");
}

2. Content Provider的query方法是否正确返回所有收藏数据?

用CursorLoader加载数据时,如果query方法逻辑错了,就算数据库里有数据也读不出来:

  • 是不是在query里返回了空Cursor,或者错误地加了过滤条件,导致只查了部分数据?
  • 数据库表的字段和query中指定的投影字段是不是不匹配?比如投影里要了poster_path,但表列叫poster_url,Cursor里自然没数据。

检查你的Content Provider的query实现,确保它正确从SQLite中读取所有收藏:

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteDatabase db = mDbHelper.getReadableDatabase();
    Cursor cursor;
    int match = sUriMatcher.match(uri);
    switch (match) {
        case MOVIES:
            // 查询整个收藏表的数据
            cursor = db.query(MovieContract.MovieEntry.TABLE_NAME,
                    projection,
                    selection,
                    selectionArgs,
                    null,
                    null,
                    sortOrder);
            break;
        // 其他单条数据查询的case...
        default:
            throw new IllegalArgumentException("无法查询未知URI: " + uri);
    }
    // 别忘了设置通知Uri,这样数据变化时CursorLoader能自动更新
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    return cursor;
}

3. SQLite数据库的表创建/版本更新是否有问题?

如果你的SQLiteOpenHelper没正确创建收藏表,或者版本更新时误删了表,数据根本没地方存:

  • 创建表的SQL语句是不是写错了?比如少了主键、字段名拼写错误,或者忘了加NOT NULL约束导致数据插入失败;
  • 数据库版本号更新后,onUpgrade方法是不是没处理好表迁移?比如直接删表重建,导致旧数据丢失。

给你个正确的表创建示例:

private static final String SQL_CREATE_MOVIES_TABLE = "CREATE TABLE " +
        MovieContract.MovieEntry.TABLE_NAME + " (" +
        MovieContract.MovieEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
        MovieContract.MovieEntry.COLUMN_MOVIE_ID + " INTEGER UNIQUE NOT NULL," + // 用电影ID做唯一约束,避免重复收藏
        MovieContract.MovieEntry.COLUMN_TITLE + " TEXT NOT NULL," +
        MovieContract.MovieEntry.COLUMN_POSTER_PATH + " TEXT NOT NULL" +
        ");";

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(SQL_CREATE_MOVIES_TABLE);
}

4. CursorLoader初始化时是否监听了正确的Uri?

如果你的CursorLoader加载的是单条影片的Uri,而不是整个收藏表的Uri,自然读不到所有收藏数据:

// 正确初始化CursorLoader的方式
getSupportLoaderManager().initLoader(MOVIE_FAV_LOADER_ID, null, this);

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String[] projection = {
            MovieContract.MovieEntry._ID,
            MovieContract.MovieEntry.COLUMN_TITLE,
            MovieContract.MovieEntry.COLUMN_POSTER_PATH
    };
    // 这里要传对应整个收藏表的CONTENT_URI,而不是单条数据的Uri
    return new CursorLoader(this,
            MovieContract.MovieEntry.CONTENT_URI,
            projection,
            null,
            null,
            null);
}

5. 验证数据是否真的写入了数据库

你可以用Android Studio的Device File Explorer找到应用的数据库文件(路径是data/data/你的包名/databases/下的.db文件),导出后用SQLite工具打开,直接查看收藏表有没有数据。如果表中没数据,说明写入逻辑有问题;如果表中有数据但加载不出来,就是读取逻辑的问题。

如果以上排查都没找到问题,建议你贴出Main Activity中收藏操作的代码,以及Content Provider的insert/query核心实现,这样能更精准地定位问题。

内容的提问来源于stack exchange,提问作者sandy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:13:49