Realm with pre populated data into assets?

2020-01-26 09:01发布

Normally I use Realm as:

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

How can I add to the assets folder of my project a database with data and read it?

标签: android realm
5条回答
手持菜刀,她持情操
2楼-- · 2020-01-26 09:42

You can use assetFile() method. Please be aware that you can't use assetFile() with deleteIfMigrationNeeded().

查看更多
我命由我不由天
3楼-- · 2020-01-26 09:43

Since Realm Java 0.91.0 there has been an assetFile(String) option on the RealmConfiguration that automatically will copy a file from assets and use that if needed (e.g. if the Realm is opened the first time or has been deleted for some reason):

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

The above will copy the file from assets the first time the Realm is opened or if it has been deleted due to migrations (remember to update the asset Realm in that case).


OLD ANSWER:

It is possible to bundle a Realm database in the assets folder, but then you just need to copy it from there when starting the app the first time.

We have an example of how to copy the files here: 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;
}
查看更多
家丑人穷心不美
4楼-- · 2020-01-26 09:49

Realm has a special parameter in its RealmConfiguration.Builder called assetFile. You could use it like:

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

just set yer assets DB path and file name and you are good to go without any android-realm-asset-helper lib or copy-file-from-assets code. In this example my app packaged DB-file lies in "assets/dataBase/default.realm".
Note, version below 2 has a bit another way to call assetFile, you should pass context additionally:

realmConfiguration = new RealmConfiguration.Builder(context)
        .assetFile(context, "dataBase/default.realm")
        .build();
查看更多
贪生不怕死
5楼-- · 2020-01-26 09:57

Since Realm 0.89.0 RealmConfiguration.initialData(Realm.Transaction) can now be used to populate a Realm file before it is used for the first time.

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);
查看更多
ゆ 、 Hurt°
6楼-- · 2020-01-26 09:58

We had a similar need, and also wanted support for a read-only realm database shared with an iOS version of the app.

We created a simple library and have open-sourced it. It includes the copy code given in @christian-melchior's answer, as well as some optional extra tracking for read-only realm database(s) bundled with the APK. Comments and PRs welcomed. See:

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

查看更多
登录 后发表回答