mhe*_*rzl 7 android android-room
我正在尝试按照此Room 文档中的描述预填充数据库。
它说
在调用 build() 之前,从 RoomDatabase.Builder 对象调用 createFromAsset() 方法
并显示以下代码:
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
.createFromAsset("database/myapp.db")
.build();
Run Code Online (Sandbox Code Playgroud)
我的问题是,这段代码去哪里了?按照Room 入门步骤,我创建了一个数据实体类、一个数据访问对象接口和一个数据库类。该代码应该只在安装或首次启动时运行一次。我不希望它在每次应用程序启动时运行,并且绝对不希望每次创建我的主要活动时运行。
我到底应该在哪里放置Room.databaseBuilder(...初始化数据库的代码?
实际上并databaseBuilder没有初始化数据库,而是返回一个AppDatabase对象(在您的情况下)。当返回的AppDatabase对象用于访问数据库(通常通过@Dao注释函数之一)时,它将打开数据库(如果存在)或初始化(创建)它。
拥有 .createFromAsset 意味着创建将从资产中复制文件,而不是根据 @Database 注释中指定为实体的类创建数据库。
简而言之,一旦数据库存在,它就存在,每次运行应用程序时都不会初始化/创建它。
通常使用单例方法,因此您有一个可以在整个应用程序中检索的 AppDatabase 对象。
我的问题是,这段代码去哪里了?
如果使用单例方法,那么可能在 AppDatabase 类中。
例如
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在活动/片段中使用上述内容,您只需使用该getInstance方法即可。这将只调用一次databaseBuilder。
只有在数据库的生命周期内第一次调用它时,才会从资产文件夹中复制数据库文件。后续构建将打开现有数据库。当应用程序运行时,不会重复构建,而是返回已构建的 AppDatabase 对象。
在一项活动(可能是许多活动)中,您可以进行以下操作:-
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 */
....
}
....
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
756 次 |
| 最近记录: |