2017-12-16 9 views
-1

私はRealm(およびAndroid開発)の新人です.Slepletonクラスを使用してRealmデータ管理を簡素化して、グループプロジェクトで友人が使用するのが簡単です。EpicPandaForceのRealmManagerを正しく実装しましたか?

EpicPandaForceはRealmManager hereと呼ばれるシングルトンクラスを書かれているが、私はそれを実装の例を見つけることができなかったので、これは私が試したものです。だから私の友人は、いくつかのデータを保存したいとき

public class RealmManager { 
    private static RealmManager instance; 
    private final ThreadLocal<Realm> localRealm = new ThreadLocal<>(); 

    RealmManager(){} 

    public synchronized static RealmManager getInstance(){ 
     if(instance == null){ 
      instance = new RealmManager(); 
     } 
     return instance; 
    } 

    public Realm openLocalInstance() { 
     Realm realm = Realm.getDefaultInstance(); 
     if(localRealm.get() == null) { 
      localRealm.set(realm); 
     } 
     return realm; 
    } 

    public Realm getLocalInstance() { 
     Realm realm = localRealm.get(); 
     if(realm == null) { 
      throw new IllegalStateException("No open Realms were found on this thread."); 
     } 
     return realm; 
    } 

    public void closeLocalInstance() { 
     Realm realm = localRealm.get(); 
     if(realm == null) { 
      throw new IllegalStateException(
       "Cannot close a Realm that is not open."); 
     } 
     realm.close(); 
     if(Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()) <= 0) { 
     localRealm.set(null); 
     } 
    } 

    public void storePreferenceDao(int userID, String rank){ 
     final PreferenceDao preferenceDao = new PreferenceDao(); 
     preferenceDao.setUserID(userID); 
     preferenceDao.setRank(rank); 
     openLocalInstance(); 
     getLocalInstance().executeTransactionAsync(new Realm.Transaction() { 
      @Override 
      public void execute(Realm realm) { 
       realm.copyToRealmOrUpdate(preferenceDao); 
      } 
     }, new Realm.Transaction.OnSuccess(){ 
      @Override 
      public void onSuccess(){ 
       System.out.println("Data is stored successfully!"); 
      } 
     }, new Realm.Transaction.OnError(){ 
      @Override 
      public void onError(Throwable error){ 
       System.out.println("There is an error in storePreferenceDao()"); 
      } 
     }); 
     closeLocalInstance(); 
    } 

彼らはちょうど使用することができます:

RealmManager.getInstance().storePreferenceDao(123, "Alpaca"); 

これはどのように使用されるはずですか、それは冗長ですか?どうすればより効率的にすることができますか?

+0

あなたのRealmManagerのクラスの 'getInstance()'をスレッドセーフで 'synchronized'としてください。 – Chithra

+0

@vinSいいえ私のアプリにEpicPandaForceのRealmManagerクラスを実装しようとしていますが、どこにも例が見つかりません。 –

+0

@Chithra Noted!ありがとう。私は今それを編集します。 –

答えて

0

するための他の任意のより良い方法を取得する場合、私に教えてください...あなたを助ける

・ホープ(そうするonSuccess/onErrorを呼ばれることはありません)トランザクションコールバックで閉じ

すでにBGスレッド

の場合は、可能ならBGスレッドで実行することができる方法、および現在のスレッド上を作ることができます
// method in RealmManager 
public final void runTransaction(Realm.Transaction transaction) { 
    runTransaction(transaction, null, null); 
} 

public final void runTransaction(Realm.Transaction transaction, Realm.Transaction.OnSuccess onSuccess) { 
    runTransaction(transaction, onSuccess, null); 
} 

public final void runTransaction(Realm.Transaction transaction, Realm.Transaction.OnSuccess onSuccess, Realm.Transaction.OnError onError) { 
    Realm realm = openLocalInstance(); 
    if(realm.isAutoRefresh()) { 
     realm.executeTransactionAsync(transaction, new Realm.Transaction.OnSuccess() { 
      @Override 
      public void onSuccess() { 
       try { 
        if(onSuccess != null) { 
         onSuccess.onSuccess(); 
        } 
       } finally { 
        closeLocalInstance(); 
       } 
      } 
     }, new Realm.Transaction.OnError() { 
      @Override 
      public void onError(Throwable e) { 
       try { 
        if(onError != null) { 
         onError.onError(e); 
        } 
       } finally { 
        closeLocalInstance(); 
       } 
      } 
     }); 
    } else { 
     try { 
      realm.executeTransaction(transaction); 
      if(onSuccess != null) { 
       onSuccess.onSuccess(); 
      } 
     } catch(Exception e) { 
      if(onError != null) { 
       onError.onError(e); 
      } 
      throw new RuntimeException(e); 
     } finally { 
      closeLocalInstance(); 
     } 
    } 
} 

このメソッドを追加すると、可能であれば、asyncトランザクションメソッドを介してバックグラウンドスレッド上で実行されるトランザクションを実行できるようになりました。synchronousルーパスレッドでない場合はトランザクションメソッド(f.ex.バックグラウンドスレッド)あなたは今、あなたは知っている

public void storePreferenceDao(int userID, String rank) { 
    final PreferenceDao preferenceDao = new PreferenceDao(); 
    preferenceDao.setUserID(userID); 
    preferenceDao.setRank(rank); 
    runTransaction(new Realm.Transaction() { 
     @Override 
     public void execute(Realm realm) { 
      realm.copyToRealmOrUpdate(preferenceDao); 
     } 
    }, new Realm.Transaction.OnSuccess(){ 
     @Override 
     public void onSuccess(){ 
      System.out.println("Data is stored successfully!"); 
     } 
    }, new Realm.Transaction.OnError(){ 
     @Override 
     public void onError(Throwable error){ 
      System.out.println("There is an error in storePreferenceDao()"); 
     } 
    }); 
} 

それとも

public void storePreferenceDao(int userID, String rank) { 
    final PreferenceDao preferenceDao = new PreferenceDao(); 
    preferenceDao.setUserID(userID); 
    preferenceDao.setRank(rank); 
    runInTransaction(new Realm.Transaction() { 
     @Override 
     public void execute(Realm realm) { 
      realm.copyToRealmOrUpdate(preferenceDao); 
     } 
    }); 
} 

を行うことができます

この方法で、私はいつも、私はその一例にrunTransaction()メソッドを追加する必要があります感じました。デフォルトではデフォルトでexecuteTransactionAsyncを使用するかどうかは議論の余地があるかどうかです。

+0

ありがとうございました!ただ1つの質問、storePreferenceDao(int、String)はまだRealmManagerクラスにありますか? –

+0

RealmManagerで作成された独自のクラスを作成することもできます(また、Roomがどのように行うかと同じように、コンストラクタパラメータとして自身を作成することもできます)。または、それをシングルトンにしてRealmManagerにコンストラクタパラメータとして与えることができます。これはDIと何をするのですか? – EpicPandaForce

+0

ありがとうございます!今はRealmManagerのすべてをコーディングします。 –

0

簡単なシングルトン例、

public class MySingleton { 
private static MySingleton sMySingleton; 

//private constructor. 
private MySingleton() { 
    if (sMySingleton != null){ 
     throw new RuntimeException("Use getInstance() for the instance"); 
    } 
} 

public synchronized static MySingleton getInstance() { 
    if (sMySingleton == null){ 
     sMySingleton = new MySingleton(); 
    } 
    return sMySingleton; 
} 
} 

はそれが役に立てば幸い!

+0

これは既に実装されています。 – EpicPandaForce

0

これは

public class BaseActivity extends AppCompatActivity { 
public Realm realm; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_base); 
     realm = Realm.getDefaultInstance(); 
    } 

} 

は、ご利用に応じて、他の活動に

public class MainActivity extends BaseActivity { 

     @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     //Here you can directly access realm object and perform your task 
     realm.where()//just example 
    } 
    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     if(realm!=null) 
      realm.close(); 
     //Don't forget to close realm object 
    } 

} 

をBaseActivityを拡張し、私のアプリケーションでは、私はレルムを使用していますどのようにここでは最良の答えではなく、することができ、私はこれがあると言っておりません一番良い方法ですが、それは一番良い方法です。この方法で私は簡単にレルムクラスを管理し、レルムに関連するエラーを減らすことができます。フラグメントについてBaseFragmentを作成し、それを他のフラグメントに拡張することができます。これはあなたが実際にこのような場合には、その方法はまだのみUIスレッドから呼び出すことができ、かつローカルインスタンスがあるべきこの

関連する問題