基于LifeCycle组件学习注解处理两种方式

1,321 阅读3分钟

Lifecycle组件使用场景

目前AppCompatActivity、Fragment实现了这个接口LifecycleOwner,方便Presenter感知View(Activity、Fragment)的生命周期。

  public class AppCompatActivity extends FragmentActivity  { xx}
  public class FragmentActivity extends ComponentActivity { xx} 
  public class ComponentActivity extends Activity implements LifecycleOwner {xx}
  
  public class Fragment implements  LifecycleOwner{xx}

Lifecycle组件使用

既然AppCompatActivity、Fragment作为LifecycleOwner,也就是被观察者,我们无需处理。 订阅者就是我们的Presenter,订阅者要做的就是

1.标记自己是订阅者

     public class MyPresenter implements LifecycleObserver {xxx}

2.对感兴趣的事件添加注解

        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        public void onMyCreate() {
            Log.e(TAG, "onCreate: " + "oncreate");
       }

Lifecycle组件大致原理

两大设计模式的运用:观察者设计模式 装饰器设计模式

被观察者:LifecycleOwner

  • 职责:
      1. 管理订阅者,怎么管理,当然是添加add和移除 remove,像极了集合的操作,对的,观察者肯定有集合。
      1. 分发事件
      private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
      public abstract void addObserver(@NonNull LifecycleObserver observer);
      public abstract void removeObserver(@NonNull LifecycleObserver observer);
      public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    

订阅者:LifecycleObserver

  • 职责:对感兴趣的事件添加注解即可。

为啥会用到装饰器模式?

  • 装饰器模式目的:方法增强

    • 第一处:当add订阅者时候,将原始Obsever封装成ObserverWithState,这样可以添加一个State变量,处理状态。 再次被封装成GenericLifecycleObserver对象,是因为处理事件分发有两种途径: a.纯反射实现(ReflectiveGenericLifecycleObserver)
      b.apt实现。(CompositeGeneratedAdaptersObserver等多个类似的类),都可以调用onStateChanged方法。
    • 第二处:apt生成的新类也是对Observer对象的封装。

LifePhaseRegistry 被观察者去履行职责----真正干活的类

管理订阅者代码没啥特色,分发的操作可以看下。分别从AppCompatActivity和Fragment来看。

  • 1.AppCompatActivity被嵌入了一个ReportFragment对象,ReportFragment的生命周期跟AppCompatActivity绑定,就可以同步调用了。
 public static void injectIfNeededIn(Activity activity) {
    // ProcessLifecycleOwner should always correctly work and some activities may not extend
    // FragmentActivity from support lib, so we use framework fragments for activities
    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        // Hopefully, we are the first to make a transaction.
        manager.executePendingTransactions();
    }
}

上面的代码很经典,glide感知宿主Activity的生命周期也是给宿主添加了一个Fragment。你想感知也可以这么做。

public class ReportFragment extends Fragment {
    @Override
    public void onStart() {
        super.onStart();
        ....
        dispatch(Lifecycle.Event.ON_START);
    }
      private void dispatch(Lifecycle.Event event) {
        ....
        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }
}
  • Fragment 系统开发人员直接在Fragment源码里面修改了代码,添加了LifecycleRegistry分发事件。
    public class Fragment implementsLifecycleOwner {
     LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
       @Override
     public Lifecycle getLifecycle() {
         return mLifecycleRegistry;
     }
    
    void performStart() {
       .....
         onStart();
         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
        ....
     }
     ....
    
     }
    

关于订阅者接收的事件

订阅者可以获取到完整的事件链,比如:你在MainAct的onStart方法里添加订阅者,那它还是可以收到onCreate事件得,因为addObserver时,这个订阅者的状态是从初始化(INITIALIZED)状态开始的 然后它要接收到onStart事件,就先从onCreate一步一步的发射事件让自身的状态值达到CREATED。

  public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
   //比如当前发射onStart事件,就可以计算出当前状态就是STARTED
   //那么集合里面的订阅者的状态还是INITIALIZED,那就一步一步的往上+,达到状态相同
      State next = getStateAfter(event);
      moveToState(next);
  }
@Override
  public void addObserver(@NonNull LifecycleObserver observer) {
      State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
      ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
      ...
      State targetState = calculateTargetState(observer);
      while ((statefulObserver.mState.compareTo(targetState) < 0
              && mObserverMap.contains(observer))) {
          statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
          targetState = calculateTargetState(observer);
      }
      .....
  }
  static State getStateAfter(Event event) {
      switch (event) {
          case ON_CREATE:
          case ON_STOP:
              return CREATED;
          case ON_START:
          case ON_PAUSE:
              return STARTED;
       ....
  }
  private static Event upEvent(State state) {
      switch (state) {
          case INITIALIZED:
          case DESTROYED:
              return ON_CREATE;
          case CREATED:
              return ON_START;
      ....
  }
  

Lifecycle组件对注解的处理

大家可以先看Lifecycle组件的源码,然后自行去简单实现两种处理注解的方式,如果不会,可以参考LifeCycele组件。

  • 纯反射 没啥技术门槛

  • apt技术

    • 1.因为在编译期间,类的处理都是Element,需要一些基本Element的常识。

      java-apt的实现之Element详解

    • 2.androidx的工程貌似不支持'com.google.auto.service:auto-service:1.0-rc4'只能老老实实的新建resource文件夹去指定注解处理器的路径。

    • 3.LifeCycle的compiler注解处理器的库可能在As里面找不到,你需要去翻Lifecycle的源码。

一个简单处理注解的实现 AnnotationDemo