2016-11-04 28 views
1

私の理解から、Realmはメインスレッドからのみアクセスできます。あるレルムから別のレルムへ非同期でコピーする

私は2つの領域を使用します.1つは、検証時に実領域に移動する「汚れた」データを格納する領域です。

これまでのところとても良いですが、私はメインスレッドの外でそうする方法を見つけることができません。 realm.executeTransactionAsync()を使用して実際の領域に書き込むと、ダーティ領域またはトランザクションスレッド内のRealmResultsにアクセスできなくなります。

唯一の回避策は、メインスレッドでdirtyRealm.copyFromRealm()を使用することです。これは、スレッドを長期間ブロックする可能性があります。

これは正しいアプローチですか、それともより良い解決策ですか?

+0

「私の理解から、レルムはメインスレッドからしかアクセスできません。間違って、レルムはそれを作成したスレッドからしかアクセスできません。 – EpicPandaForce

+0

@EpicPandaForceそれが私が書いた理由です。最初に 'RealmObject'をすべてメモリ内のコピーにコピーすることなく、自分の見解ではアクセスできなくなりました。それをお勧めしますか? – ferbeb

+0

私は言った、あなたはあなたがその特定のスレッドで開くレルムにアクセスすることができます。これは、UIスレッドでUIスレッドRealmにアクセスできないことを意味しません。 – EpicPandaForce

答えて

1

、1はこの問題に対して迅速な回避策を採用することができます。

executeTransactionAsyncブロック内での簡単な同期のクエリ(のようなfindAll())とrealm.copyFromRealm(results)を使用してください - 実行するのは良い習慣ではないかもしれません書き込み操作を含まないトランザクションですが、コード全体を変更することなくジョブを完了させます。

TLDR;クエリとcopyFromRealmをexecuteTransactionAsyncブロックに移動します。

0

領域であることを行うための標準的な方法は、私がレルムでこれを行うための標準的な方法がないと思わthis comment by beeender

に応じてありません。 RealmObjectAには、2つのパラメータ、1つはRealmObjectA、もう1つはRealmObjectBをとるcopyToRealmObjectBのような静的関数を作成したいと思います。静的関数内のsetterとgetterを呼び出してコピーを実行します。申し訳ありませんが、通常の妥当な要件のようには見えません。 RealmObjectを代わりに使用するのはなぜですか?私の理解からrealm.io/docs/java/latest/#field-types

+0

私がそれを理解しているので、あなたが言及したコメントは、SettersとGettersを使わずに、RealmObjectを拡張する1つのClassAからRealmObjectを拡張するClassBにデータをコピーすることを参照しています。これは私の問題ではなく、スレッディングや複数の 'Realm'インスタンスの使用とは関係がないと私は考えていません。 – ferbeb

1

を参照してください、レルムは/のみメインスレッドからアクセスされなければならないことができます。

これは誤解です。 Realmはルーパースレッド(メインスレッドなど)でのみ自動更新されますが、これはの任意のスレッドに新しいRealmインスタンスを作成することはできません。あなたがバックグラウンドスレッドでレルムを開きたい場合は

、あなたは簡単にこれを行うことができます:

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     Realm firstRealm = null; 
     Realm secondRealm = null; 
     try { 
      firstRealm = Realm.getInstance(firstConfiguration); 
      secondRealm = Realm.getInstance(secondConfiguration); 

      firstRealm.beginTransaction(); 
      secondRealm.beginTransaction(); 
      RealmResults<SomeObject> someObjects = firstRealm.where(SomeObject.class) 
                  .equalTo(SomeObjectFields.VALID, true) 
                  .findAll(); 
      secondRealm.copyToRealmOrUpdate(someObjects); // I am not sure if you have to detach it first. 
      someObjects.deleteAllFromRealm(); 
      secondRealm.commitTransaction(); 
      firstRealm.commitTransaction(); 
     } catch(Throwable e) { 
      if(firstRealm != null && firstRealm.isInTransaction()) { 
       firstRealm.cancelTransaction(); 
      } 
      if(secondRealm != null && secondRealm.isInTransaction()) { 
       secondRealm.cancelTransaction(); 
      } 
      throw e; 
     } finally { 
      if(firstRealm != null) { 
       firstRealm.close(); 
      } 
      if(secondRealm != null) { 
       secondRealm.close(); 
      } 
     } 
    } 
}).start(); 

そして、UIスレッド上で要素にアクセスするには、UIスレッドレルムと必要なだけだろうRealmResultsRealmChangeListenerが結合されている。

EpicPandaForcesの答えに代わり
public class MainActivity extends AppCompatActivity { 
    Realm realm; 

    @BindView(R.id.realm_recycler) 
    RecyclerView recyclerView; 

    RealmResults<SomeObject> listenerSet; 
    RealmChangeListener realmChangeListener = new RealmChangeListener() { 
     @Override 
     public void onChange(Object element) { 
      if(recyclerView != null && recyclerView.getAdapter() != null) { 
       recyclerView.getAdapter().notifyDataSetChanged(); 
      } 
     } 
    }); 

    @Override 
    public void onCreate(Bundle bundle) { 
     super.onCreate(bundle); 
     realm = Realm.getDefaultInstance(); 
     setContentView(R.layout.activity_main); 
     ButterKnife.bind(this); 

     listenerSet = realm.where(SomeObject.class).findAll(); 
     listenerSet.addChangeListener(realmChangeListener); 

     // set up recyclerView 

     adapter.updateData(realm.where(SomeObject.class).findAll()); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     if(realm != null) { 
      realm.close(); 
      realm = null; 
     } 
    } 
} 
+0

バックグラウンド領域のデータをメインスレッドにどのように取得するのですか?私はあなたがバックグラウンドスレッドで分離コピーを作成し、何とかメインスレッドに通知してそれらをフェッチする必要があると思います。 – Zackline

+0

こんにちは?レルムは、バックグラウンドスレッドでコミットすると自動的にそれを実行し、RealmChangeListenerに通知しますか? – EpicPandaForce

+0

異なるレルムインスタンスを同じレルムデータベース上で動作させることはできますか?それは確かにここでより安全な人生になるでしょう。 – Zackline

関連する問題