2017-01-20 9 views
1

レルムを使用するレポジトリパターンを実装しようとしていて、レルムインスタンスの作成とクローズを処理中にライブオブジェクト機能を保持します。これは私の現在のアプローチであり、残念ながらそれは機能しません。カスタムバックグラウンドスレッドですべてのコードを実行します。ライブオブジェクトと内部レルムインスタンス処理でレルムを使用するレポジトリパターン

public Observable<List> getAll(Class clazz) { 
    Realm realm = Realm.getDefaultInstance(); 
    SerializedSubject relay = new SerializedSubject<>(PublishSubject.create()); 
    try { 
     realm.where(clazz).findAllAsync().addChangeListener(new RealmChangeListener<RealmResults>() { 
       @Override 
       public void onChange(RealmResults element) { 
         relay.onNext(realm.copyFromRealm(element)); 
       } 
     }); 
     return relay.asObservable(); 
    } finally { 
     relay.onCompleted(); 
     try { 
      if (!realm.isClosed()) 
       realm.close(); 
     } catch (IllegalStateException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

バックグラウンドスレッド:

public class JobExecutor implements ThreadExecutor { 

private static final int INITIAL_POOL_SIZE = Runtime.getRuntime().availableProcessors(); 
// Sets the amount of time an idle thread waits before terminating 
private static final int KEEP_ALIVE_TIME = 10; 
// Sets the Time Unit to seconds 
private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS; 
@NonNull 
private final ThreadPoolExecutor threadPoolExecutor; 

public JobExecutor() { 
    threadPoolExecutor = new ThreadPoolExecutor(INITIAL_POOL_SIZE, INITIAL_POOL_SIZE, 
      KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, new LinkedBlockingQueue<>(), new JobThreadFactory()); 
} 

@Override 
public void execute(@NonNull Runnable runnable) { 
    this.threadPoolExecutor.execute(runnable); 
} 

private static class JobThreadFactory implements ThreadFactory { 
    private static final String THREAD_NAME = "android_"; 
    private int counter = 0; 

    @NonNull 
    @Override 
    public Thread newThread(@NonNull Runnable runnable) { 
     return new Thread(runnable, THREAD_NAME + counter++); 
    } 
} 

私はこのようにそれを使用します。

private <T> Observable.Transformer<T, T> applySchedulers() { 
    return observable -> observable.subscribeOn(Schedulers.from(mThreadExecutor)) // my background thread 
      .observeOn(mPostExecutionThread.getScheduler()); // main thread 
} 

この例外がスローされます。

java.lang.IllegalStateException: Your Realm is opened from a thread without a Looper. Async queries need a Handler to send results of your query 

私は.findAllを(使用)の代わりに.findAllAsync()のこの例外がスローされます:

java.lang.IllegalStateException: You can't register a listener from a non-Looper thread or IntentService thread. 

ご協力いただきありがとうございます。

+0

お探しの回答がありますか? –

+0

@TimCastelijns ルーパーを使用してバックグラウンドスレッドを作成する方法。だから私はsubscribeOn(AndroidSchedulers.from(BackgroundLooper)) –

答えて

1

IllegalStateExceptionで指定されているように、ルーパー/ハンドラを持つスレッドが必要です。今、あなたはAndroidSchedulerではなく、通常のSchedulersクラスを使用しているようです。 Android固有のスケジューラのこのレポをご覧ください。

https://github.com/ReactiveX/RxAndroid/tree/1.x/rxandroid/src/main/java/rx/android/schedulers

+0

私は謝罪、私は自分の実装をバックグラウンドスレッドのために使用している私の心を逃した。私は正しい実装で投稿を編集しました。私のカスタム実装と同じルーパを使ってパフォーマンスを引き出す方法はありますか?両方またはいずれかのオプションの例を提供してください。再度、感謝します –

関連する問題