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

替换Shared Preferences为Room Database后数据无法持久化

问题描述

我是自学开发者,基础知识可能有疏漏,还请见谅。之前用Shared Preferences存游戏数据,后来根据Google Play Console的错误提示和调研,换成了推荐的Room Database。更新游戏后,从onStart恢复时数据能正常读取,游戏可以接着上次的进度玩,但应用销毁后重新打开,所有游戏数据都丢了,得从零开始,应该是漏掉了数据写入本地存储和读取的关键步骤。我不需要具体代码,只想要需要研读/调研的方向指引,我的代码是Java,相关代码如下:


实体类代码

@Entity(tableName = "DatabasePiles")
public class DatabasePiles {

    @PrimaryKey (autoGenerate = true)
    @ColumnInfo(name = "pile_id")
    public int pile_id;

    @ColumnInfo(name = "db_pile_number")
    public Integer db_pile_number;

    @ColumnInfo(name = "db_card_1")
    public Integer db_card_1;

    @ColumnInfo(name = "db_card_2")
    public Integer db_card_2;

    /// constructor, getters, setters, etc.
} 

DAO接口代码

@Dao
public interface DatabasePilesDAO {

     @Insert
    public void addDatabasePile(DatabasePiles databasePiles);

    @Query("select * from databasePiles")
    public List<DatabasePiles> getAllDatabasePiles();

    @Query("select * from databasepiles where pile_id ==:pile_id")
    public DatabasePiles getDataBasePile(int pile_id);
}

数据库类代码

@Database(entities = {DatabasePiles.class}, version = 1)
public abstract class DatabaseForDatabasePiles extends RoomDatabase {

    public abstract  DatabasePilesDAO getDatabasePilesDAO();

}

数据保存代码

RoomDatabase.Callback myCallBack = new RoomDatabase.Callback() {
    @Override
    public void onCreate(@NonNull SupportSQLiteDatabase db) {
        super.onCreate(db);
    }

    @Override
    public void onOpen(@NonNull SupportSQLiteDatabase db) {
        super.onOpen(db);
    }
};


dbForDatabasePiles = Room.databaseBuilder(getApplicationContext(), DatabaseForDatabasePiles.class,"DBForDatabasePiles").addCallback(myCallBack).build();


int[] example = new int[]{1, 2, 3};
int pile_id = 1;

DatabasePiles examplePile1 = new DatabasePiles(pile_id, example[0], example[1], example[2]);

dbForDatabasePiles.getDatabasePilesDAO().addDatabasePile(examplePile1);

数据检索代码

DatabasePiles dbPile = dbForDatabasePiles.getDatabasePilesDAO().getDataBasePile(1);
// where (1) is the pile_id

调研方向指引
  • Room线程操作规范:Room默认禁止在主线程执行数据库读写操作,若你的插入/查询操作在主线程执行,可能会被系统阻断,导致数据未实际写入。需研究Room的异步实现方式,比如用AsyncTask、Executor或RxJava处理数据库操作。
  • 数据库实例单例模式:若每次操作都新建DatabaseForDatabasePiles实例,可能引发连接异常,导致数据写入失败。需确保整个应用仅存在一个数据库实例,这是Room的核心最佳实践。
  • 数据写入确认机制:执行插入操作后,需验证是否成功完成。比如修改@Insert方法返回long类型的插入ID,或者使用事务保证数据写入的原子性,避免中途异常导致数据丢失。
  • 主键策略冲突排查:你的实体类设置了autoGenerate = true,但又手动指定pile_id,这可能导致主键逻辑冲突。需明确主键是自动生成还是手动管理,以及数据存在时的覆盖/跳过逻辑。
  • 数据库文件存储验证:通过Android Studio的Device File Explorer查看/data/data/[你的应用包名]/databases/目录,确认是否生成了对应的数据库文件,排查存储路径和权限问题。
  • 应用销毁前的持久化时机:在应用即将被销毁时(如onPause或onDestroy生命周期),确保所有待写入数据已完成操作,避免进程被直接杀死导致数据未持久化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:48:10