将数据预填充到资产中的领域?

Realm with pre populated data into assets?

通常我将 Realm 用作:

RealmConfiguration config = new RealmConfiguration.Builder(applicationContext).deleteRealmIfMigrationNeeded().build();

如何将包含数据的数据库添加到项目的资产文件夹并读取它?

自 Realm Java 0.91.0 以来,RealmConfiguration 上有一个 assetFile(String) 选项,它会自动从资产中复制文件并在需要时使用该文件(例如,如果 Realm首次打开或因故被删除):

RealmConfiguration config = new RealmConfiguration.Builder()
  .assetFile("path/to/file/in/assets") // e.g "default.realm" or "lib/data.realm"
  .deleteRealmIfMigrationNeeded()
  .build()

以上内容会在第一次打开 Realm 时从资产中复制文件,或者如果它因迁移而被删除(请记住在这种情况下更新资产 Realm)。


旧答案:

可以在 assets 文件夹中捆绑一个 Realm 数据库,但是您只需在第一次启动应用程序时从那里复制它即可。

这里有一个如何复制文件的例子:https://github.com/realm/realm-java/blob/master/examples/migrationExample/src/main/java/io/realm/examples/realmmigrationexample/MigrationExampleActivity.java#L101-Lundefined

copyBundledRealmFile(this.getResources().openRawResource(R.raw.default_realm), "default.realm");

private String copyBundledRealmFile(InputStream inputStream, String outFileName) {
    try {
        File file = new File(this.getFilesDir(), outFileName);
        FileOutputStream outputStream = new FileOutputStream(file);
        byte[] buf = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buf)) > 0) {
            outputStream.write(buf, 0, bytesRead);
        }
        outputStream.close();
        return file.getAbsolutePath();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

[编辑] 请参阅下面 Stan 的回答。显然 Realm 现在直接支持这个所以你可以忽略这个答案(除非你使用旧的 Realm 版本)。

我们有类似的需求,也希望支持与 iOS 版本的应用程序共享的只读领域数据库。

我们创建了一个简单的库并将其开源。它包括@christian-melchior 的回答中给出的复制代码,以及一些可选的对与 APK 捆绑在一起的只读领域数据库的额外跟踪。欢迎评论和 PR。参见:

https://github.com/eggheadgames/android-realm-asset-helper

由于 Realm 0.89.0 RealmConfiguration.initialData(Realm.Transaction) 现在可以在首次使用之前用于填充 Realm 文件。

RealmConfiguration conf = new RealmConfiguration.Builder(context)
.initialData(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                  realm.beginTransaction();
                  realm.createObject(....)
                  realm.commitTransaction();
                }
            }).deleteRealmIfMigrationNeeded().name("mRealm.db").build();
Realm realm = Realm.getInstance(conf);

您可以使用assetFile()方法。请注意,您不能将 assetFile()deleteIfMigrationNeeded() 一起使用。

Realm 在其 RealmConfiguration.Builder 中有一个名为 assetFile 的特殊参数。您可以像这样使用它:

realmConfiguration = new RealmConfiguration.Builder()
                    .assetFile("dataBase/default.realm") // your app's packaged DB
                    ...
                    .build();

只需设置您的资产数据库路径和文件名,您就可以不用任何 android-realm-asset-helper 库或从资产复制文件代码。在这个例子中,我的应用程序打包的 DB 文件位于 "assets/dataBase/default.realm"。
注意,低于 2 的版本有另一种调用 assetFile 的方式,您应该另外传递上下文:

realmConfiguration = new RealmConfiguration.Builder(context)
        .assetFile(context, "dataBase/default.realm")
        .build();