重用Realm数据库的快照

时间:2016-03-27 22:24:21

标签: android database realm realm-migration

我有一个Realm数据库每秒都会多次填充数据。我正在将数据库视为绘制的MPChartLib数据。我的目标是在特定时间点拍摄数据库的图片,稍后重复使用该信息。

我正在尝试几种方法并且两者都陷入了僵局。我的第一种方法是拥有第二个Realm数据库,我可以通过点击按钮填充第一个数据库中的信息。我的第二种方法是将数据库导出到一个文件,然后稍后重新打开它。

在我的第一种方法中,我在onCreateView中构建了两个数据库,如下所示。我使用mRealm作为动态变化的Realm,使用mSRealm作为静态的,仅在按钮点击时更改。

  // Building a Realm instance un-persisted in memory (ie not on disk)
    RealmConfiguration config1 = new RealmConfiguration.Builder(getActivity())
            .name("myDynamic.realm")
            .inMemory()
            .build();
    // Building a Realm instance on disk)
    RealmConfiguration config2 = new RealmConfiguration.Builder(getActivity())
            .name("myStatic.realm")
            .build();
    Log.i(TAG, "delete previous");
    Realm.deleteRealm(config2);
    Realm.deleteRealm(config1); // Clean slate
    Log.i(TAG, "set default configuration");
    Realm.setDefaultConfiguration(config1); // Make this Realm the default
    Log.i(TAG, "define an instance for this");
    mRealm = buildDatabase(config1);
    mSRealm = buildDatabase(config2);

    Log.i(TAG, "build a Listener for database changes");
    realmListener = new RealmChangeListener() {
        @Override
        public void onChange() {
            //        Log.i(TAG, "database changed");
            if (startTime != 0) {
                //        Log.i(TAG, "off to plot");
                setData();
                mChart.invalidate();
            }
        }
    };

    Log.i(TAG, "add Listener  ");
    mRealm.addChangeListener(realmListener);

每个配置的buildDatabase代码

  public Realm buildDatabase(RealmConfiguration config){

    try {
        Log.i(TAG, "return database since there was not already one ");
        return Realm.getInstance(config);
    } catch (RealmMigrationNeededException e){
        try {
            Log.i(TAG, "deleted database since there was one");
            Realm.deleteRealm(config);
            Log.i(TAG, "return new database since there was one deleted");
            return Realm.getInstance(config);
        } catch (Exception ex){
            Log.i(TAG, "should not ever get here");
            throw ex;
        }
    }
}

当mRealm数据库完成它的事务时,我测试是否通过按钮push将recordData标志设置为true。如果是这样,那么我将数据库导出为文件和/或尝试将静态数据库快照更新为动态数据库的当前状态。

   //    Log.i(TAG, "copy element to the database ");
        mRealm.copyToRealm(entry);
        //        Log.i(TAG, " database  has size =  " + results.size());
        mRealm.commitTransaction();

        if (recordData) {
            Log.i(TAG, "record copy to file ");
            exportDatabase(mRealm);
            Log.i(TAG, "record copy to static Database ");
            copyToStaticDatabase(mRealm);
        //    Log.i(TAG, "record to singleton ");
        //    updateDataLab();
            recordData = !recordData;
        }

使用以下方法将数据导出到文件中

    public void exportDatabase(Realm mRealm ) {
    Log.i(TAG, "into export the database to a file ");
    File exportRealmFile = null;
    try {
        // get or create an "export.realm" file
        Log.i(TAG, "get or create file ");
        exportRealmFile = new File(getActivity().getExternalCacheDir(), "export.realm");

        // if "export.realm" already exists, delete
        exportRealmFile.delete();

        // copy current realm to "export.realm"
        try {
            Log.i(TAG, "write copy to file ");
            mRealm.writeCopyTo(exportRealmFile);
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
    }catch (IOException e) {
            e.printStackTrace();
        }

使用以下方法复制到静态基础

  public void copyToStaticDatabase(Realm mRealm ){

    Log.i(TAG, "get query of current state ");
    RealmResults<DataEntry> result2 = mRealm.where(DataEntry.class).findAllSorted("timestamp");
    Log.i(TAG, "delete old and create new static database ");
    Realm mSRealm = buildDatabase(config2);
    Log.i(TAG, "begin repopulating static database ");
    mSRealm.beginTransaction();

    for (int i = 0; i < result2.size(); i++) {
        DataEntry entry = mSRealm.createObject(DataEntry.class);
        entry.setX(result2.get(i).getX());
        entry.setY(result2.get(i).getY());
        entry.setZ(result2.get(i).getZ());
        entry.setTimestamp(result2.get(i).getTimestamp());
        entry.setAccuracy(result2.get(i).getAccuracy());
        entry.setsTimestamp(result2.get(i).getsTimestamp());

        mRealm.copyToRealm(entry);
    }
    Log.i(TAG, "finish static database ");
    mSRealm.commitTransaction();
}

此代码在创建mSRealm的新实例时已经死亡,因为&#34;开始填充等等#34;永远不会显示在日志中。不知道我在那里做错了什么。

 Log.i(TAG, "delete old and create new static database ");
    Realm mSRealm = buildDatabase(config2);
    Log.i(TAG, "begin repopulating static database ");

我想转到一个新片段并使用静态数据库。在新片段的onCreateView中,我尝试创建一个指向静态Realm的配置:

    // Building a Realm instance on disk
    RealmConfiguration config = new RealmConfiguration.Builder(getActivity())
            .name("myStatic.realm")
            .build();
    Log.i(TAG, "keep previous");
//    Realm.deleteRealm(config); // Clean slate
    Log.i(TAG, "set default configuration");
    Realm.setDefaultConfiguration(config); // Make this Realm the default
    Log.i(TAG, "define an instance for this");
    mRealm = Realm.getDefaultInstance();

我无法对此进行测试,因为我的代码会在我的尝试副本中停止。对于文件方法,我尝试使用我已经重写为fragment的MigrationExampleActivity,并将其包含在我的项目中,以测试如何通过版本更新执行迁移。这将变得更加重要,因为将快照存档以供将来长期参考非常重要。

我认为这是重新加载&#34;来自我在其他问题上阅读的文件中的数据库。我的代码在获取新实例的下方再次崩溃。

@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
                         Bundle savedInstanceState) {

    Log.i(TAG, " in onCreate  View ");
    View view = inflater.inflate(R.layout.activity_realm_basic_example, container, false);


    rootLayout = ((LinearLayout) view.findViewById(R.id.container));
    rootLayout.removeAllViews();
    Log.i(TAG, " get resources of previous database  ");

    copyBundledRealmFile(this.getResources().openRawResource(R.raw.default1), "default1");

    Log.i(TAG, " set up new configuration ");
    RealmConfiguration config1 = new RealmConfiguration.Builder(getActivity())
            .name("default1")
            .schemaVersion(3)
            .migration(new Migration())
            .build();
    Log.i(TAG, " get new instance ");
    realm = Realm.getInstance(config1); // Automatically run migration if needed
    Log.i(TAG, " got new instance ");
    showStatus("Default1");
    showStatus(realm);
    realm.close();

    return view;
}

我试图在我的项目中模仿realmjavamaster的结构,但也许我在设置原始目录时遇到了问题。关于如何利用&#34;居民&#34;我不太清楚领域以及如何引用重新打开它们,获得正确的路径等。

可能是我的问题出在引用中,或者我在获取新实例时不了解足够的细节。也许我错过了一些基本的东西。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

好的,所以我花了一些时间来完成Realm数据库的基础知识,现在我们都设置了在一个片段中使用多个领域,保存和检索我积极变化的领域的快照静态领域。

我的问题是基于对模型类的模式定义的基本缺乏理解以及在对这些模型类进行更改时迁移到新版本的方法。以及对如何以及在何处存储领域的一些基本误解。

我还发现使用域数据库作为在片段之间传递数据的方法的巨大好处。我现在有一个名为&#34; GlobalVariables&#34;我可以在我的项目中的任何片段中读取和写入。对我来说没有更多碎片了!或使用&#34;托管活动&#34;在片段之间传递数据。

我只是在想要数据的地方打开GlobalVariables的一个实例! 此外,我可以将GlobalVariables的变体存储为记录,以允许我的应用程序上的特定操作类型的自定义设置。

谢谢你,cmelchior和Realm,勇敢......