2016-07-26 13 views
3

ActivityまたはFragmentのObservableを購読する場合は、rxlifecycle-components or rxlifecycle-naviを使用して、それぞれのライフサイクルにバインドする必要があることを知っています。Android - ビュー所有者のRx観測可能なサブスクリプション:ライフサイクルの処理方法

しかし、私は今ViewHolder(extend RecyclerView.ViewHolder)の中から観測可能なものを購読しています。ビューが破棄され、サブスクリプションがアクティブのままであればどうなるか心配です。

どのライフサイクルにこの観察可能物をバインドする必要がありますか?

答えて

1

私はうまくいけば、質問を書いている間に答えを見つけました。

ほとんどのアダプターはコンストラクターでContextパラメーターを受け取ります。たとえば:

public MyAdapter(Context context, ...) { ... } 

我々は中にもコンテキストとして作品を回すRxActivityを受け取るためにそれを変更することができます:ViewHolder

public MyAdapter(RxActivity parent, ...) { 
    this.parent = parent; 
    ... 
} 

そして今を:

myObservable 
    .compose(parent.bindToLifecycle()) 
    .subscribe(); 

これはことを保証します親(アクティビティーまたはフラグメント)が破棄された場合、サブスクリプションは終了します。

4

RecyclerView.Adapterには、引数のサブスクリプションを閉じることができるonViewRecycled(ViewHolder)というメソッドがあります。

0

アクティビティのライフサイクルを管理するためにサードパーティ製のライブラリは必要ありません。試してみてください以下のコード:

public class LifecycleBinder { 

    public static <R> Observable.Transformer<R, R> subscribeUtilEvent(final Activity target, LifecycleEvent event) { 
     final Application app = target.getApplication(); 
     final PublishSubject<LifecycleEvent> publishSubject = PublishSubject.create(); 
     final Application.ActivityLifecycleCallbacks callbacks = new Application.ActivityLifecycleCallbacks() { 
      @Override 
      public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 

      } 

      @Override 
      public void onActivityStarted(Activity activity) { 

      } 

      @Override 
      public void onActivityResumed(Activity activity) { 

      } 

      @Override 
      public void onActivityPaused(Activity activity) { 
       if (activity == target) 
        publishSubject.onNext(LifecycleEvent.ON_PAUSED); 
      } 

      @Override 
      public void onActivityStopped(Activity activity) { 
       if (activity == target) 
        publishSubject.onNext(LifecycleEvent.ON_STOPPED); 
      } 

      @Override 
      public void onActivitySaveInstanceState(Activity activity, Bundle outState) { 
       if (activity == target) 
        publishSubject.onNext(LifecycleEvent.ON_SAVE_INSTANCE_STATE); 
      } 

      @Override 
      public void onActivityDestroyed(Activity activity) { 
       if (activity == target) 
        publishSubject.onNext(LifecycleEvent.ON_DESTROYED); 
      } 
     }; 

     app.registerActivityLifecycleCallbacks(callbacks); 
     return subscribeUtilEvent(publishSubject, event, new Action0() { 
      @Override 
      public void call() { 
       app.unregisterActivityLifecycleCallbacks(callbacks); 
      } 
     }); 
    } 

    public static <R> Observable.Transformer<R, R> subscribeUtilEvent(final Fragment target, LifecycleEvent event) { 
     final FragmentManager manager = target.getFragmentManager(); 
     if (manager == null) { 
      throw new NullPointerException("fragment manager is null!"); 
     } 

     final PublishSubject<LifecycleEvent> publishSubject = PublishSubject.create(); 
     final FragmentManager.FragmentLifecycleCallbacks callbacks = manager.new FragmentLifecycleCallbacks() { 

      @Override 
      public void onFragmentPreAttached(FragmentManager fm, Fragment f, Context context) { 
      } 

      @Override 
      public void onFragmentAttached(FragmentManager fm, Fragment f, Context context) { 
      } 

      @Override 
      public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) { 
      } 

      @Override 
      public void onFragmentActivityCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) { 
      } 

      @Override 
      public void onFragmentViewCreated(FragmentManager fm, Fragment f, View v, Bundle savedInstanceState) { 
      } 

      @Override 
      public void onFragmentStarted(FragmentManager fm, Fragment f) { 
      } 

      @Override 
      public void onFragmentResumed(FragmentManager fm, Fragment f) { 
      } 

      @Override 
      public void onFragmentPaused(FragmentManager fm, Fragment f) { 
       if (f == target) 
        publishSubject.onNext(LifecycleEvent.ON_PAUSED); 
      } 

      @Override 
      public void onFragmentStopped(FragmentManager fm, Fragment f) { 
       if (f == target) 
        publishSubject.onNext(LifecycleEvent.ON_STOPPED); 
      } 

      @Override 
      public void onFragmentSaveInstanceState(FragmentManager fm, Fragment f, Bundle outState) { 
       if (f == target) 
        publishSubject.onNext(LifecycleEvent.ON_SAVE_INSTANCE_STATE); 
      } 

      @Override 
      public void onFragmentViewDestroyed(FragmentManager fm, Fragment f) { 
       if (f == target) 
        publishSubject.onNext(LifecycleEvent.ON_VIEW_DESTORYED); 
      } 

      @Override 
      public void onFragmentDestroyed(FragmentManager fm, Fragment f) { 
       if (f == target) 
        publishSubject.onNext(LifecycleEvent.ON_DESTROYED); 
      } 

      @Override 
      public void onFragmentDetached(FragmentManager fm, Fragment f) { 
       if (f == target) 
        publishSubject.onNext(LifecycleEvent.ON_DESTROYED); 
      } 
     }; 
     manager.registerFragmentLifecycleCallbacks(callbacks, true); 

     return subscribeUtilEvent(publishSubject, event, new Action0() { 
      @Override 
      public void call() { 
       manager.unregisterFragmentLifecycleCallbacks(callbacks); 
      } 
     }); 
    } 

    private static <R, T> Observable.Transformer<R, R> subscribeUtilEvent(final Observable<T> source, final T event, final Action0 doOnComplete) { 
     return new Observable.Transformer<R, R>() { 
      @Override 
      public Observable<R> call(Observable<R> rObservable) { 
       return rObservable.takeUntil(takeUntilEvent(source, event)).doOnCompleted(doOnComplete); 
      } 
     }; 
    } 

    private static <T> Observable<T> takeUntilEvent(final Observable<T> src, final T event) { 
     return src.takeFirst(new Func1<T, Boolean>() { 
      @Override 
      public Boolean call(T lifecycleEvent) { 
       return lifecycleEvent.equals(event); 
      } 
     }); 
    } 
} 

ライフサイクルイベント:

public enum LifecycleEvent { 
    ON_PAUSED, 
    ON_STOPPED, 
    ON_SAVE_INSTANCE_STATE, 
    ON_DESTROYED, 
    ON_VIEW_DESTORYED, 
    ON_DETACHED, 
} 

使用法:

myObservable 
    .compose(LifecycleBinder.subscribeUtilEvent(this, LifecycleEvent.ON_DESTROYED)) 
    .subscribe(); 
関連する問題