【问题标题】:Android - Rx observable subscription in view holder: How to handle lifecycle?Android - 视图持有者中的 Rx 可观察订阅:如何处理生命周期?
【发布时间】:2016-07-26 01:11:52
【问题描述】:

我知道如果我订阅 Activity 或 Fragment 中的 observable,我应该使用 rxlifecycle-components or rxlifecycle-navi 将其绑定到它们各自的生命周期。

但是,我现在正在从 ViewHolder(扩展 RecyclerView.ViewHolder)中订阅一个 observable,我担心如果视图被销毁并且订阅仍然处于活动状态会发生什么。

我应该将此可观察对象绑定到哪个生命周期以及如何绑定?

【问题讨论】:

    标签: android android-lifecycle rx-android


    【解决方案1】:

    RecyclerView.Adapter 有一个方法onViewRecycled(ViewHolder),您可以在其中关闭ViewHolder 参数的订阅。

    【讨论】:

    • 我确实在onViewRecycled 上实现了调用,但我所有的一次性物品在创建后都被丢弃了......这种方法真的是正确的地方吗?
    【解决方案2】:

    希望我在写问题时找到了答案。

    大多数适配器在其构造函数中接收Context 参数等。例如:

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

    我们可以将其更改为接收RxActivity,这反过来也可以作为上下文:

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

    现在在ViewHolder:

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

    这确保了任何订阅都将在父级(活动或片段)被销毁时结束。

    【讨论】:

      【解决方案3】:

      您不需要任何第三方库来管理 Activity 生命周期。试试下面的代码:

      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();
      

      【讨论】:

      猜你喜欢
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      • 2022-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-26
      • 1970-01-01
      相关资源
      最近更新 更多