EventBus原理解析和手写(一)

先在android studio添加引用:

implementation 'org.greenrobot:eventbus:3.1.1'

EventBus常规用法:

EventBus原理解析和手写(一)_第1张图片

FirstActivity的xml布局和代码




  

  
public class FirstActivity extends AppCompatActivity {
  private static final String TAG = "FirstActivity";

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_first);
    EventBus.getDefault().register(this);
  }

  public void onClick(View view) {
    startActivity(new Intent(this, SecondActivity.class));
  }

  @Subscribe(threadMode = ThreadMode.MAIN)
  public void onMessageEvent(MessageEvent event) {
    Log.e(TAG, getClass().getSimpleName() + "接收到的信息是:" + event.getMsg());
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);
  }
}

EventBus原理解析和手写(一)_第2张图片

SecondActivity的xml布局和代码




  
  
public class SecondActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
  }

  public void sendMessage(View view) {
    EventBus.getDefault().post(new MessageEvent(getClass().getSimpleName() + "发出消息"));
  }
}

输出结果:

EventBus原理解析和手写(一)_第3张图片

现在我们来尝试编写一下eventbus框架

1、我们先注释掉eventbus引用

EventBus原理解析和手写(一)_第4张图片

同步结果FristActivity和SecondActivity代码如下:

EventBus原理解析和手写(一)_第5张图片

EventBus原理解析和手写(一)_第6张图片

很显然,我们要通过四个类实现EventBus

1、创建线程模式

2、创建注解

3、封装方法类

4、"存储"方法,并通过反射调用

步骤一:先创建EventBus类

很显然,从上面用法看出,EventBus.getDefault()是个单例模式,开始编写EventBus类

public class EventBus {
  private static volatile EventBus instance;

  private EventBus() {

  }

  public static EventBus getDefault() {
    if (instance == null) {
      synchronized (EventBus.class) {
        if (instance == null) {
          instance = new EventBus();
        }
      }
    }
    return instance;
  }
}

创建线程模式:

public enum ThreadMode {
  POSTING,

  MAIN,

  MAIN_ORDERED,

  BACKGROUND,

  ASYNC
}
创建注解类:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Subscribe {
  ThreadMode threadMode() default ThreadMode.MAIN;
}

现在来封装方法EventBus原理解析和手写(一)_第7张图片

public class EventBus {
  private static volatile EventBus instance;

  private EventBus() {

  }

  public static EventBus getDefault() {
    if (instance == null) {
      synchronized (EventBus.class) {
        if (instance == null) {
          instance = new EventBus();
        }
      }
    }
    return instance;
  }

  public void register(Object object) {

  }
}

现在我们来理一下思路:因为有可能Activity和Fragment或者说其他类,有可能会有多个接收方法,如

EventBus原理解析和手写(一)_第8张图片

EventBus发出消息,可能也有多个类都接收,所以显然我们需要定义一个map类,来储存哪个类有哪几个方法是需要接收信息

public class EventBus {
  private Map> registerMap;//key用来存储是哪个类,value是该类下的所有接收方法
  private static volatile EventBus instance;

  private EventBus() {
    registerMap = new HashMap<>();
  }

  public static EventBus getDefault() {
    if (instance == null) {
      synchronized (EventBus.class) {
        if (instance == null) {
          instance = new EventBus();
        }
      }
    }
    return instance;
  }

  public void register(Object object) {

  }
}
public class MethodManager {
  private Class type;//参数类型
  private ThreadMode threadMode;//线程模式
  private Method method;

  public MethodManager(Class type, ThreadMode threadMode, Method method) {
    this.type = type;
    this.threadMode = threadMode;
    this.method = method;
  }

  public Class getType() {
    return type;
  }

  public void setType(Class type) {
    this.type = type;
  }

  public ThreadMode getThreadMode() {
    return threadMode;
  }

  public void setThreadMode(ThreadMode threadMode) {
    this.threadMode = threadMode;
  }

  public Method getMethod() {
    return method;
  }

  public void setMethod(Method method) {
    this.method = method;
  }
}

我们再来分析一下,接收的方法注解类一定是我们自定义的,且方法的参数是有且只有一个,返回值为void

public class EventBus {
  private Map> registerMap;//key用来存储是哪个类,value是该类下的所有接收方法
  private static volatile EventBus instance;

  private EventBus() {
    registerMap = new HashMap<>();
  }

  public static EventBus getDefault() {
    if (instance == null) {
      synchronized (EventBus.class) {
        if (instance == null) {
          instance = new EventBus();
        }
      }
    }
    return instance;
  }

  public void register(Object object) {
    List methodList = registerMap.get(object);
    if (methodList == null) {
      methodList = findAnotationMethod(object);
      registerMap.put(object, methodList);
    }

  }

  private List findAnotationMethod(Object object) {
    List methodList = new ArrayList<>();
    Class clazz = object.getClass();
    Method[] methods = clazz.getMethods();
    for (Method method : methods) {
      Subscribe subscribe = method.getAnnotation(Subscribe.class);
      if (subscribe == null) {
        continue;
      }
      //特性1:是无返回值的
      Type returnType = method.getGenericReturnType();
      if (!"void".equals(returnType.toString())) {
        throw new RuntimeException(method.getName() + "方法返回值必须是void");
      }
      //特性二:方法参数有且只有一个
      Class[] parameterTypes = method.getParameterTypes();
      if (parameterTypes.length != 1) {
        throw new RuntimeException(method.getName() + "方法参数有且只有一个");
      }
      //完全符合了要求
      MethodManager methodManager = new MethodManager(parameterTypes[0], subscribe.threadMode(), method);
      methodList.add(methodManager);
    }
    return methodList;
  }

  /**
   * 发送消息
   *
   * @param setter 方法参数
   */
  public void post(Object setter) {
    Set set = registerMap.keySet();
    for (Object key : set) {
      //遍历哪些类中的方法接收的参数类型符合,发送者。
      List methodList = registerMap.get(key);
      for (MethodManager methodManager : methodList) {
        if (methodManager.getType().isAssignableFrom(setter.getClass())) {
          try {
            methodManager.getMethod().invoke(key, setter);//方法调用
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }
  }

  /**
   * 接收类
   *
   * @param object 接受者
   */
  public void unregister(Object object) {
    if (registerMap.get(object) != null) {
      registerMap.remove(object);
    }
  }
} 
  

运行结果:

 

你可能感兴趣的:(android)