EventBus原理解析和手写(一)

先在android studio添加引用:

implementation 'org.greenrobot:eventbus:3.1.1'

EventBus常规用法:

FirstActivity的xml布局和代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  >

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="First Activty"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    />

  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="onClick"
    android:text="跳转"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    />

</android.support.constraint.ConstraintLayout>
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);
  }
}

SecondActivity的xml布局和代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  >

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Second Activity!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    />
  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="sendMessage"
    android:text="EventBus"
    android:textAllCaps="false"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    />

</android.support.constraint.ConstraintLayout>
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框架

1、我们先注释掉eventbus引用

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

很显然,我们要通过四个类实现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;
}

现在来封装方法

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

public class EventBus {
  private Map<Object, List<MethodManager>> 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<Object, List<MethodManager>> 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<MethodManager> methodList = registerMap.get(object);
    if (methodList == null) {
      methodList = findAnotationMethod(object);
      registerMap.put(object, methodList);
    }

  }

  private List<MethodManager> findAnotationMethod(Object object) {
    List<MethodManager> 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<Object> set = registerMap.keySet();
    for (Object key : set) {
      //遍历哪些类中的方法接收的参数类型符合,发送者。
      List<MethodManager> 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);
    }
  }
}

运行结果:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值