2016-03-27 45 views
0

我有一個Realm數據庫每秒被填充數據數次。我正在將數據庫查看爲繪製的MPChartLib數據。我的目標是在特定時間點拍攝數據庫的圖片,稍後再使用該信息。重新使用Realm數據庫的快照

我正在嘗試幾種方法,並在兩者中都陷入了僵局。我的第一種方法是有第二個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); 

併爲每個配置

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數據庫已經完成了它的交易我測試,看看是否通過按下按鈕的recordData標誌已設置爲true buildDatabase代碼。如果是這樣,那麼我將數據庫作爲文件導出並/或嘗試將靜態數據庫快照更新爲動態數據庫的當前狀態。

// 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的新實例,因爲「開始填充等」永遠不會顯示在日誌中。不知道我在那裏做錯了什麼。

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

我想去一個新的片段,並使用靜態數據庫。在onCreateView新片段我嘗試創建一個指向靜態領域的配置:

// 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(); 

,因爲我的代碼停在我試圖複製我卻無法進行測試。對於文件方法,我嘗試通過MigrationExampleActivity進行工作,我已將其重寫爲片段並將其包含在我的項目中,以測試如何通過版本更新執行遷移。這將變得更加重要,因爲重要的是將快照存檔以供將來長期參考。

我認爲這是從我從其他問題閱讀過的文件中「重新加載」數據庫的方式。我的代碼在得到一個新實例的時候再次崩潰。

@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在我的項目中的結構,但也許我有一個設置原始目錄的問題。我不清楚如何利用「常駐」領域,以及如何參考重新開放它們,獲得正確的道路等。

可能是我的問題是在引用,或者我不知道獲取新的實例足夠的細節。也許我錯過了一些基本的東西。

任何幫助,非常感謝。

+0

什麼是崩潰時的異常消息? – beeender

+0

對不起,我錯過了你的提示問題。這裏是我得到:java.lang.NullPointerException:嘗試調用空對象上的虛擬方法'io.realm.RealmObjectSchema io.realm.RealmObjectSchema.addRealmListField(java.lang.String,io.realm.RealmObjectSchema)'參考 at com.tomphyx.android.accelwear1.database.Migration.migrate(Migration.java:98) –

+0

上述錯誤來自我嘗試實施MigrationExample。這是由於我對模式缺乏瞭解。如何定義等。 –

回答

1

好的,所以我花了一些時間來研究Realm數據庫的基礎知識,現在我已經設置了在一個片段內使用多個領域,保存和檢索我主動變化領域的快照靜態領域。

我的問題是基於對模型類的模式定義有些基本的缺乏理解,以及在對這些模型類進行更改時遷移到新版本的方式。除了對存儲領域的方式和領域存在一些基本的誤解。

我也發現使用領域數據庫作爲在片段之間傳遞數據的方法的巨大好處。我現在有一個名爲「GlobalVariables」的數據庫,可以在我的項目中的任何片段中讀寫數據。沒有更多的片段爲我參與!或通過使用「託管活動」在片段之間傳遞數據。

我只需在任何需要數據和完成的地方打開GlobalVariables實例! 此外,我可以將GlobalVariables的變體存儲爲記錄,以便爲我的應用上的特定操作類型進行自定義設置。

感謝beender,cmelchior和Realm,bravo ...

+0

只是好奇,你還在使用兩個領域的快照? – beeender

+0

在我的Fragment DataEntryPlot中,我可以查看領域數據庫DataEntry,它每秒會發生多次更改。一旦我喜歡數據的外觀,我點擊Snapshot按鈕執行Realm.writeCopyTo(exported.realm)然後,我在片段MeasurePlot中重新打開此文件,以對此靜態Realm進行分析。如果我喜歡這些數據,我可以點擊MeasurePlot快照按鈕,該按鈕爲Realm.writeCopyTo(uniqueFilename)提供測量的存檔存儲。運行良好,就像「存儲」型示波器一樣。接下來,我正在研究用於文件管理的雲/加密存儲 –

+0

更直接地,我在DataEntryPLot中有一個主動變化的領域,我將其導出爲temporary文件並在MeasurePlot中重新打開。 DataEntryPlot的每次導出都會覆蓋臨時文件。 –