使用 android 的 'Room',`Room.databaseBuilder(...` 代码去哪儿了?
Using android's 'Room', where does the `Room.databaseBuilder(...` code go?
我正在尝试按照 this 房间文档中的描述预填充数据库。
它说到
call the createFromAsset() method from your RoomDatabase.Builder
object before calling build()
并显示以下代码:
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
.createFromAsset("database/myapp.db")
.build();
我的问题是,这段代码去哪儿了?按照 getting started with Room 的步骤,我创建了一个数据实体 class、一个数据访问对象接口和一个数据库 class。此代码应该 运行 一次,在安装或首次启动时。我不希望每次应用程序启动时它都 运行,而且绝对不是每次我的主要 activity 创建时。
初始化数据库的 Room.databaseBuilder(...
代码具体放在哪里?
databaseBuilder
实际上并没有初始化数据库,而是 returns 一个 AppDatabase
对象(在你的例子中)。当返回的 AppDatabase
对象用于访问数据库(通常通过 @Dao 注释函数之一)时,它将打开数据库(如果存在)或初始化(创建)它。
拥有 .createFromAsset 意味着创建将从资产复制文件,而不是根据在 @Database 注释中指定为实体的 classes 创建数据库。
总之数据库一旦存在就存在,不会initialised/created,每次App都是运行.
通常使用单例方法,因此您有一个在整个应用程序中检索的 AppDatabase 对象。
My question is, where does this code go?
如果使用单例方法,则可能在 AppDatabase 中 class。
例如
@Database(
entities = {/* the @Entity annotated classes here */},
version = 1,
exportSchema = false
)
abstract class AppDatabase extends RoomDatabase {
abstract AllDAO getAllDAO(); /* one for each @Dao annotated interface or abstract class */
private static volatile AppDatabase instance = null;
static AppDatabase getInstance(Context context) {
if (instance == null) {
instance /* i.e. an instance of the AppDatabase */ = Room.databaseBuilder(
context,
AppDatabase.class,
"Sample.db"
)
.createFromAsset("database/myapp.db")
.build();
}
return instance;
}
}
- 请注意,这不会进入单身人士的issues/complexities
因此,对于 activity/fragment 中的上述内容,您只需使用 getInstance
方法即可。这将在整个过程中只调用一次 databaseBuilder。
只有在数据库的生命周期内第一次调用它时,才会从资产文件夹中复制数据库文件。后续构建将打开现有数据库。
当应用 运行 构建时,不会重复构建,而是返回已经构建的 AppDatabase 对象。
在 activity(可能有很多活动)中,您可以举个例子:-
public class MainActivity extends AppCompatActivity {
AppDatabase sampleDb;
AllDAO dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sampleDb = AppDatabase.getInstance(this);
dao = sampleDb.getAllDAO();
/* AT THIS STAGE THE DATABASE WILL NOT HAVE BEEN INITIALISED */
/* Either of the following would initialise the database */
/* NOTE following would fail as trying to access on the main thread, could use .allowMainThreadQueries in databaseBuilder */
dao.????????; /* use one of the functions from the respective @Dao annotated interface or abstract class */
/* OR FORCE an OPEN e.g. */
SupportSQLiteDatabase openSampleDb = sampleDb.getOpenHelper().getWritableDatabase();
/* Note that you could force an open in the getInstance method if wanted, but typically not so */
....
}
....
}
我正在尝试按照 this 房间文档中的描述预填充数据库。
它说到
call the createFromAsset() method from your RoomDatabase.Builder object before calling build()
并显示以下代码:
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
.createFromAsset("database/myapp.db")
.build();
我的问题是,这段代码去哪儿了?按照 getting started with Room 的步骤,我创建了一个数据实体 class、一个数据访问对象接口和一个数据库 class。此代码应该 运行 一次,在安装或首次启动时。我不希望每次应用程序启动时它都 运行,而且绝对不是每次我的主要 activity 创建时。
初始化数据库的 Room.databaseBuilder(...
代码具体放在哪里?
databaseBuilder
实际上并没有初始化数据库,而是 returns 一个 AppDatabase
对象(在你的例子中)。当返回的 AppDatabase
对象用于访问数据库(通常通过 @Dao 注释函数之一)时,它将打开数据库(如果存在)或初始化(创建)它。
拥有 .createFromAsset 意味着创建将从资产复制文件,而不是根据在 @Database 注释中指定为实体的 classes 创建数据库。
总之数据库一旦存在就存在,不会initialised/created,每次App都是运行.
通常使用单例方法,因此您有一个在整个应用程序中检索的 AppDatabase 对象。
My question is, where does this code go?
如果使用单例方法,则可能在 AppDatabase 中 class。
例如
@Database(
entities = {/* the @Entity annotated classes here */},
version = 1,
exportSchema = false
)
abstract class AppDatabase extends RoomDatabase {
abstract AllDAO getAllDAO(); /* one for each @Dao annotated interface or abstract class */
private static volatile AppDatabase instance = null;
static AppDatabase getInstance(Context context) {
if (instance == null) {
instance /* i.e. an instance of the AppDatabase */ = Room.databaseBuilder(
context,
AppDatabase.class,
"Sample.db"
)
.createFromAsset("database/myapp.db")
.build();
}
return instance;
}
}
- 请注意,这不会进入单身人士的issues/complexities
因此,对于 activity/fragment 中的上述内容,您只需使用 getInstance
方法即可。这将在整个过程中只调用一次 databaseBuilder。
只有在数据库的生命周期内第一次调用它时,才会从资产文件夹中复制数据库文件。后续构建将打开现有数据库。 当应用 运行 构建时,不会重复构建,而是返回已经构建的 AppDatabase 对象。
在 activity(可能有很多活动)中,您可以举个例子:-
public class MainActivity extends AppCompatActivity {
AppDatabase sampleDb;
AllDAO dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sampleDb = AppDatabase.getInstance(this);
dao = sampleDb.getAllDAO();
/* AT THIS STAGE THE DATABASE WILL NOT HAVE BEEN INITIALISED */
/* Either of the following would initialise the database */
/* NOTE following would fail as trying to access on the main thread, could use .allowMainThreadQueries in databaseBuilder */
dao.????????; /* use one of the functions from the respective @Dao annotated interface or abstract class */
/* OR FORCE an OPEN e.g. */
SupportSQLiteDatabase openSampleDb = sampleDb.getOpenHelper().getWritableDatabase();
/* Note that you could force an open in the getInstance method if wanted, but typically not so */
....
}
....
}