EventBus是一种用于Android的事件发布-订阅总线,由GreenRobot开发,Gihub地址是:EventBus。它简化了应用程序内各个组件之间进行通信的复杂度,尤其是碎片之间进行通信的问题,可以避免由于使用广播通信而带来的诸多不便。
像这样的框架如何进行实现呢,我们就手写一个。
枚举类,用于线程切换。
public enum ThreadMode {
MAIN,BACKGROUND
}
注解@Target:用于描述注解的使用范围,ElementType.METHOD,用于描述方法。
注解@Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期。RetentionPolicy.RUNTIME,代表在运行时有效。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Subscribe {
ThreadMode threadMode() default ThreadMode.MAIN;
}
用于存放方法和类
public class SubscribeMethod {
//回调方法
private Method mMethod;
//线程模式
private ThreadMode mThreadMode;
//方法中的参数
private Class> type;
public SubscribeMethod(Method mMethod, ThreadMode mThreadMode, Class> type) {
this.mMethod = mMethod;
this.mThreadMode = mThreadMode;
this.type = type;
}
public Method getmMethod() {
return mMethod;
}
public void setmMethod(Method mMethod) {
this.mMethod = mMethod;
}
public ThreadMode getmThreadMode() {
return mThreadMode;
}
public void setmThreadMode(ThreadMode mThreadMode) {
this.mThreadMode = mThreadMode;
}
public Class> getType() {
return type;
}
public void setType(Class> type) {
this.type = type;
}
}
发送消息实体类
public class EventBean {
private int state;
private String message;
public EventBean(int state, String message) {
this.state = state;
this.message = message;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "EventBean{" +
"state=" + state +
", message='" + message + '\'' +
'}';
}
}
public class EventBus {
private Map
在MainActivity 中注册并接收消息
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//注册
EventBus.getDefault().register(this);
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void getMessage(EventBean bean) {
Log.i("MainActivity", "getMessage: bean=" + bean.toString());
}
}
在SecondActivity 中发送消息
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
findViewById(R.id.second_tv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new EventBean(1001,"你好"));
}
});
}
}
很简单的实现方式,当然在实际开发中还需要更多的代码,去完善EventBus。这里只说明了,用最简单的方式去实现一个EventBus,核心思想就是注解和反射,很好理解。
https://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650264045&idx=1&sn=08ec3b416144a435fb557d51007c137c&chksm=88632082bf14a994b3bb10b63185c32b39e855e40103434a52fe6066254e96ae7718c29eccd4&scene=27
EventBus 是一种事件发布/订阅框架,它实现了发布/订阅模式,提供了一种异步的、松散耦合的消息传递机制。
EventBus 的主要实现机制还是基于反射和编译时注解(APT),一句话概括就是:
EventBus 如何切回主线程的:
EventBus在初始化的时候会初始化一个MainThreadSupport对象,它会去获取主线程的Looper对象并存起来。这个mainThreadPoster其实是Handler的子类,它利用Handler的消息机制切换线程。
APT(Annotation Processing Tool)
是一种编译时注解处理工具,它可以在编译 Java 代码时扫描指定的注解,并根据注解生成相应的代码。APT 可以帮助开发者在编译时自动生成代码,减少重复劳动,提高代码的复用性和可维护性。
APT 的工作原理如下:
APT 可以帮助开发者自动生成很多有用的代码,例如自动生成代码检查器、数据库映射器、事件监听器等。APT 还可以与其他框架和工具结合使用,例如与 Dagger、ButterKnife 等依赖注入框架结合使用,可以大大简化代码的编写和维护工作。
Java注解是一种用于提供元数据的Java语言特性。它们允许在Java代码中添加额外的信息,这些信息可以用于编译时检查、运行时处理或者生成代码。注解可以应用于类、方法、字段和其他程序元素。
Java注解的原理可以通过以下步骤来理解:
1.定义注解:使用@interface关键字定义一个注解。注解本质上是一个接口,其中的方法称为成员。成员可以有默认值,也可以没有。
public @interface MyAnnotation {
String value() default "default value";
int count() default 0;
}
2.注解的使用:在代码中使用注解,可以用于修饰类、方法、字段等。可以为注解的成员赋值。
@MyAnnotation(value = "Hello", count = 5)
public class MyClass {
@MyAnnotation(count = 2)
private int myField;
@MyAnnotation
public void myMethod() {
// 方法体
}
}
3.元数据的获取:使用Java的反射机制可以在运行时获取注解的信息。可以获取注解类型、成员值等。
Class<?> clazz = MyClass.class;
MyAnnotation classAnnotation = clazz.getAnnotation(MyAnnotation.class);
System.out.println(classAnnotation.value()); // 输出:Hello
Field field = clazz.getDeclaredField("myField");
MyAnnotation fieldAnnotation = field.getAnnotation(MyAnnotation.class);
System.out.println(fieldAnnotation.count()); // 输出:2
Method method = clazz.getDeclaredMethod("myMethod");
MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);
System.out.println(methodAnnotation.value()); // 输出:default value
编译时注解和运行时注解是在使用时机和处理方式上有所区别的。
编译时注解(Compile-time Annotations):
运行时注解(Runtime Annotations):