自定义注解在MVP中的使用

在Mvp架构中Activity需要创建Presenter对象,并处理与Presenter的绑定、解除绑定关系,这是View层公共的逻辑,可以把这些逻辑抽取到Base中统一处理,然而一个Activity中可能需要创建多个Presenter对象,这就需要在Activity中创建一个List列表来存储这个页面中所有的Presenter对象,在具体的子类Activiy中并不确定到底有多少个Presenter对象,解决这个问题可以为子类提供一个抽象方法,通过实现这个抽象方法子类Activity将所有创建的Presenter对象手动添加进去,这样操作起来会有点麻烦,而且在实际编码过程中还经常会忘记这步操作。这里通过自定义注解的方式来解决这个问题,具体就是通过为Presenter变量添加注解,在基类中解析注解信息自动创建Presenter对象、自动维护List列表和相关逻辑,做到子类完全不用关心这些操作,下面看下代码实现:

1、创建自定义注解类

package com.znh.commonlib.base.inject;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by znh on 2019/6/3
 */
@Target(ElementType.FIELD) //注释1
@Retention(RetentionPolicy.RUNTIME) //注释2
public @interface InjectPresenter {

}

上述代码就定义了一个注解InjectPresenter,注释1代表该注解作用于成员变量,注释2代表该注解是运行时注解。

2、创建基类BaseMvpActivity处理相关逻辑

package com.znh.commonlib.base;

import android.os.Bundle;
import android.support.annotation.Nullable;

import com.znh.commonlib.base.inject.InjectPresenter;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by znh on 2019/6/3
 * 

* MvpActivity基类 */ public abstract class BaseMvpActivity extends RxAppCompatActivity implements IBaseView { //存储当前页面中对应的所有的Presenter public List<BasePresenter> mPresenters; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayoutId()); //处理Presenter的创建和绑定 mPresenters = new ArrayList<>(); createAndBindPresenter(); initView(); initData(); } /** * 获取页面布局id * * @return */ public abstract int getLayoutId(); /** * 初始化View */ protected abstract void initView(); /** * 初始化数据 */ protected abstract void initData(); /** * 创建并绑定Presenter */ public void createAndBindPresenter() { //通过反射注入Presenter Field[] fields = this.getClass().getDeclaredFields(); for (Field field : fields) { InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class); if (injectPresenter != null) { //注释3 if (!BasePresenter.class.isAssignableFrom(field.getType())) { throw new RuntimeException("InjectPresenter annotations have incorrect field types and can only be used for BasePresenter and its subclasses"); } Class<? extends BasePresenter> basePresenterClazz = (Class<? extends BasePresenter>) field.getType(); try { //注释4 创建对象 BasePresenter basePresenter = basePresenterClazz.newInstance(); basePresenter.attachView(this); //设置字段 field.setAccessible(true); field.set(this, basePresenter); //注释5 添加Presenter mPresenters.add(basePresenter); } catch (Exception e) { e.printStackTrace(); } } } } /** * 解绑Presenter */ public void unBindPresenter() { for (BasePresenter basePresenter : mPresenters) { basePresenter.detachView(); } } @Override protected void onDestroy() { super.onDestroy(); unBindPresenter(); } }

在onCreate方法中创建mPresenters列表用来存储页面中所有的Presenter对象,然后调用createAndBindPresenter方法创建页面中所有的Presenter对象,并处理绑定逻辑,在注释3处校验注解作用的字段是否是BasePresenter类型的,如果不是就抛出异常,注释4处通过反射创建出Presenter实例对象并和View进行绑定,注释5处将创建的Presenter实例对象添加到集合列表中进行管理。在Activity的onDestroy方法中调用unBindPresenter方法对所有跟这个Activity有绑定关系的Presenter进行解除绑定,防止内存泄漏。

3、在代码中直接使用注解

package com.znh.commonlib.base;

import com.znh.commonlib.base.inject.InjectPresenter;

/**
 * Created by znh on 2019/6/3
 * 

* 测试页面 */ public class TestActivity extends BaseMvpActivity { @InjectPresenter private Presenter1 mPresenter1; @InjectPresenter private Presenter2 mPresenter2; @InjectPresenter private Presenter3 mPresenter3; public void loadData() { mPresenter1.loadData(); mPresenter2.loadData(); mPresenter3.loadData(); } ........... }

在Activity子类中如果需要使用哪个Presenter,就直接将对应的Presenter声明为成员变量并为其添加@InjectPresenter注解,就可以直接在代码中调用对应Presenter的方法,不需要关心其他的操作。

你可能感兴趣的:(Android)