【发布时间】:2020-06-06 20:13:17
【问题描述】:
我非常坚持这一点。我正在关注 Google 的“ArchitectureComponentsBasic1”,您可以通过转到 File -> New -> Import Sample 将其导入 Android Studio。我也遵循了 Maxim 在this SO 文章中提供的建议。什么都没有工作。如何让 OnCreate 回调运行,以便预填充我的数据库?
数据库:请注意,我正在我的 buildDatabase 方法中运行执行程序,以尝试运行一个虚拟查询以根据上面链接的 SO 运行 getWritableDatabase()。这不起作用。
version = 1,
exportSchema = false)
public abstract class ProjectDatabase extends RoomDatabase {
private final MutableLiveData<Boolean> isDatabaseCreated = new MutableLiveData<>();
private static ProjectDatabase instance;
private static final String DATABASE_NAME = "project.db";
private static final String TAG = ProjectDatabase.class.getSimpleName();
public abstract ProjectDao projectDao();
public static ProjectDatabase getInstance(final Context context, final AppExecutors appExecutors) {
if (instance == null) {
synchronized (ProjectDatabase.class) {
if (instance == null) {
instance = buildDatabase(context.getApplicationContext(), appExecutors);
instance.updateDatabaseCreated(context.getApplicationContext());
}
}
}
return instance;
}
private static ProjectDatabase buildDatabase(final Context appContext, final AppExecutors appExecutors) {
Log.d(TAG, "building database.");
ProjectDatabase db = Room.databaseBuilder(appContext, ProjectDatabase.class, DATABASE_NAME)
.addCallback(new Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
Log.d(TAG, "callback was called.");
appExecutors.diskIO().execute(() -> {
ProjectDatabase database = ProjectDatabase.getInstance(appContext, appExecutors);
List<Project> projects = DataGenerator.generateProjects();
Log.d(TAG, "project data: " + projects.get(0).getTitle());
insertData(database, projects);
database.setDatabaseCreated();
});
}
})
.build();
appExecutors.diskIO().execute(new Runnable() {
@Override
public void run() {
Log.d(TAG, "populate database");
db.projectDao().populateDatabase();
}
});
return db;
}
/**
* Check whether the database already exists and expose it via {@link #getDatabaseCreated()}
*/
private void updateDatabaseCreated(final Context context) {
if (context.getDatabasePath(DATABASE_NAME).exists()) {
setDatabaseCreated();
}
}
private void setDatabaseCreated(){
Log.d(TAG, "database created");
isDatabaseCreated.postValue(true);
}
private static void insertData(final ProjectDatabase database, final List<Project> projects) {
database.runInTransaction(() -> {
database.projectDao().insertAll(projects);
});
}
DAO 项目
@Dao
public interface ProjectDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insertAll(List<Project> projects);
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(Project project);
@Query("SELECT * FROM project")
LiveData<List<Project>> loadAllProjects();
@Query("SELECT * FROM project WHERE is_favorite = 1")
LiveData<Project[]> getAllFavorites();
@Query("SELECT is_favorite FROM project WHERE id = :projectId")
int isFavorite(int projectId);
@Query("UPDATE project SET is_favorite = 1 WHERE id = :projectId")
int addToFavorites(int projectId);
@Query("UPDATE project SET is_favorite = 0 WHERE id = :projectId")
int removeFromFavorites(int projectId);
// Dummy query needed to activate the Room callback method to prepopulate the database
@Query("SELECT * from project")
LiveData<Project> populateDatabase();
}
【问题讨论】:
-
您好,我可以理解您的
Callback()在您第一次打开应用程序时没有在您的数据库上调用? -
@Zain 是的,回调没有被调用。根据我的阅读,在您对数据库执行第一个操作之前,不会调用 onCreate 回调。这就是我添加 db.projectDao.populateDatabase 的原因,它旨在对虚拟数据进行数据库操作。但即使它被调用,onCreate 回调仍然没有被调用。
-
返回数据库实例后能否尝试从
ViewModel调用updateDatabaseCreated() -
这与问题没有任何关系。问题是 onCreate 回调没有被调用。
-
你不想使用out-of-box way for prepopulating in Room吗?我猜你提到的文章和例子有点过时了。这些更改是在 October 2019 的 Room 中进行的。
标签: android android-room android-architecture-components