2017-09-19 5 views
0

私は頻繁に使うwriteToRealmメソッドを持っています。そして、私は別のスレッドからそれを使用し、定型コードをカットする必要があります。この仕事のためのより良い方法は何ですか?異なるスレッドからのレルムトランザクション

private boolean writeToRealm(String user, String id) { 

     SubscriberObject subscriber = new SubscriberObject(); 

     if(mRealm.where(SubscriberObject.class) 
       .equalTo(SubscriberObject.ID,id).findAll().isEmpty() 
       &&mRealm.where(SubscriberObject.class) 
       .equalTo(SubscriberObject.USERNAME,user).findAll().isEmpty()) { 
      subscriber.setId(id); 
      subscriber.setUsername(user); 
      mRealm.beginTransaction(); 
      mRealm.insert(subscriber); 
      mRealm.commitTransaction(); 
      return true; 
     } 
     return false; 

}

私は以下の構造(またはこのようなもの)を使用する予定ですが、私は、正しい施工を作成することはできません:私は作成する必要が

public static Boolean writeToRealm(final String user,final String id){ 
     Realm mRealm; 
     return Flowable.using(
       mRealm = Realm.getDefaultInstance(), 
       new Function<Realm, Boolean>() { 
        @Override 
        public Boolean apply(@NonNull Realm realm) throws Exception { 
         SubscriberObject subscriber = new SubscriberObject(); 
         if(realm.where(SubscriberObject.class) 
           .equalTo(SubscriberObject.ID,id).findAll().isEmpty() 
           &&realm.where(SubscriberObject.class) 
           .equalTo(SubscriberObject.USERNAME,user).findAll().isEmpty()) { 
          subscriber.setId(id); 
          subscriber.setUsername(user); 
          realm.beginTransaction(); 
          realm.insert(subscriber); 
          realm.commitTransaction(); 
          return true; 
         } 
         return false; 
        } 
       }, 
       mRealm.close()).subscribeOn(Schedulers.io()); 
    } 

であってもよいしこのタスクのためにルーパーを持つスレッドクラス?

この方法と同様の方法をクリーンなアーキテクチャに統合する方法を教えてください。

+0

を探して新しいスレッドを生成し、初めて重い操作をレルムオブジェクトをされてきていると思う、私はあなたを推薦しますExecutorService –

+0

Sarthak Mittalを使ってみましたが、私はそれについて考えましたが、毎回インスタンスを作成しなければならず、変更を制御するルーパーが必要です。 – Delphian

+0

UIスレッド以外にもルーパーが必要な場合は、HandlerThreadを使用してください。 :) –

答えて

1

私はあなただけで、またexecuteTransaction()を使用して好むください

private boolean writeToRealm(String user, String id) { 
    try(Realm realm = Realm.getDefaultInstance()) {   
     if(realm.where(SubscriberObject.class).equalTo(SubscriberObject.ID,id).count() <= 0L 
       && realm.where(SubscriberObject.class).equalTo(SubscriberObject.USERNAME,user).count() <= 0L) { 
      final SubscriberObject subscriber = new SubscriberObject(); 
      subscriber.setId(id); 
      subscriber.setUsername(user); 
      realm.executeTransaction(r -> r.insert(subscriber)); 
      return true; 
     } 
    } 
    return false; 
} 
+0

EpicPandaForceご協力いただきありがとうございます。私は1つの問題を理解できません。非同期メソッドではなくUIスレッドを使用する場合は、このメソッドを使用する方法、作成するスレッドのみ?レルム・アカデミーは、ルーパー・ワークの詳細を記述していません。たとえば:私は新しいスレッドメソッドまたはFlowable.subscribeOnを開始し、 "there" writeToRealmメソッドを(このスレッドに)配置します。どの瞬間に変更が保存されますか?レルムインスタンスを閉じる前にそれらを保存できますか?ルーパーなしのスレッドで正しく動作しますか? – Delphian

+0

これは同期メソッド呼び出しであり、Flowableにする理由はありません。 – EpicPandaForce

+0

はい、わかりました。しかし、もし私がたくさんのデータを書いたら、私はUIスレッドとAsyncメソッドを使うことをやめてしまいました。たとえば、私は新しいThread(new Runnable ... writeToRealm)を開始します。このアプローチにはどのような問題がありますか?この例では、領域インスタンスを閉じる必要がありましたか?また、私は以下のコメントを追加しました。 – Delphian

0

私はこれが道に簡単解決策になると思う:

public static Boolean writeToRealm(String user, String id) { 
    Realm realm = Realm.getDefaultInstance(); 
    SubscriberObject subscriber = new SubscriberObject(); 
    if (realm.where(SubscriberObject.class).equalTo("ID", id).or().equalTo("USERNAME", user).findAll().isEmpty()){ 
     subscriber.setId(id); 
     subscriber.setUsername(user); 
     realm.beginTransaction(); 
     realm.insert(subscriber); 
     realm.commitTransaction(); 
     realm.close(); 
     return true; 
    } 
    realm.close(); 
    return false; 
} 

あなたには、いくつかのexplainationsが必要な場合は、ちょうど私が言うと、私はそれを実装します:)

PSを:私はあなたの質問をmissunderstood場合、聞かせて私は知っている!

+0

Pier Giorgio Misley、答えを説明できますか?上記の私の2つのコメントを読んでください。 – Delphian

0

非同期トランザクションのサポートは現在executeTransactionとしてではなく、代わりに同じスレッドでレルムを開くのと同じように動作し、それがバックグラウンド・レルムが別のスレッドで開かれたあなたを与えるだろう。また、トランザクションの完了時または失敗時に通知を受けたい場合は、コールバックを登録することもできます。

realm.executeTransactionAsync(new Realm.Transaction() { 
    @Override 
    public void execute(Realm realm) { 
     Dog dog = realm.where(Dog.class).equalTo("age", 1).findFirst(); 
     dog.setName("Fido"); 
    } 
}, new Realm.Transaction.OnSuccess() { 
    @Override 
    public void onSuccess() { 
     Log.d("REALM", "All done updating."); 
     Log.d("BG", t.getName()); 
    } 
}, new Realm.Transaction.OnError() { 
    @Override 
    public void onError(Throwable error) { 
     // transaction is automatically rolled-back, do any cleanup here 
    } 
}); 

read more

+0

この方法は2つの理由から良くありません。最初のものは、別のスレッドからrealmインスタンス(create/close)を制御する必要があり、閉じてしまうことを忘れてしまいます。 2番目の1つの非同期領域プールには制限があります。これは、非同期スレッドがタスクが待機している制限を超えている場合を意味します。 – Delphian

0

あなたが非同期的にお取引を行いたい場合は、boolean戻り値の型を持つことはできませんまず第一に。 Interfaceの結果を呼び出し元に返すか、RxJavaのような他の手段を選択する必要があります。

あなたに例を挙げてください。

RxJavaの方法(これは最も簡単な方法だろうと):

public static Flowable<Boolean> writeToRealm(final String user,final String id) { 
    return Flowable.fromCallable(
     new Callable<Boolean>() { 
      @Override 
      public Boolean call() throws Exception { 
       Realm realm = Realm.getDefaultInstance(); 
       if(realm.where(SubscriberObject.class) 
        .equalTo(SubscriberObject.ID,id).findAll().isEmpty() 
        &&realm.where(SubscriberObject.class) 
        .equalTo(SubscriberObject.USERNAME,user).findAll().isEmpty()) { 
        SubscriberObject subscriber = new SubscriberObject(); 
        subscriber.setId(id); 
        subscriber.setUsername(user); 
        realm.beginTransaction(); 
        realm.insert(subscriber); 
        realm.commitTransaction(); 
        mRealm.close(); 
        return true; 
       } 
       mRealm.close(); 
       return false; 
     } 
    }); 
} 

あなたは、その特定のスレッド上でトランザクションを実行するために必要なスレッド/ schedularに返さFlowableをサブスクライブします。

+0

カルペシュ・パテルルーパーはどうですか?私が知っているスレッドにルーパーがいなければ、変更は起こりません。そして、私たちはスレッドがルーパーを持っているかどうかを制御する必要がありますか?しかし、それを正しく行う方法は? – Delphian

+0

あなたはどういう意味ですか? – EpicPandaForce

+0

私はデータベースの変更について話しました。どの瞬間にデータベースが変わるのですか?トランザクションを閉じるかコミットしますか? (非ルーパースレッドの場合)たとえば、UIとバックグラウンド(非ルーパー)の2つのスレッドがある場合、これらのスレッドから同じ要素が変更されます。これはどうやって起こるでしょうか? – Delphian

関連する問題