我们熟悉的EvnetBus总线事件框架原理是使用java的反射机制,接下来我们利用这个机制自己实现一个总线事件框架。
一、总线框架
1、MyEventBus类
package jjy.jjyeventbus;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Created by JJY on 2017/3/26.
*/
public class MyEventBus {
private Map<Class<?>,Subscriber> methodMap = new HashMap<Class<?>,Subscriber>();
private static MyEventBus myEventBus = null;
private MyEventBus(){};
public static MyEventBus getInstance(){
if(myEventBus==null){
synchronized(MyEventBus.class){
if(myEventBus==null){
myEventBus = new MyEventBus();
}
}
}
return myEventBus;
}
public void register(Object obj){
Class cls = obj.getClass();
Method method = findMethod(cls);
Subscriber subscriber = new Subscriber(method,obj);
if(method!=null)
methodMap.put(cls,subscriber);
}
private Method findMethod(Class cls){
Method[] methods = cls.getDeclaredMethods();
for(Method method : methods){
SubAnnotation annotation = method.getAnnotation(SubAnnotation.class);
if(annotation!=null)
return method;
}
return null;
}
public void post(Object object){
for(Map.Entry<Class<?>,Subscriber> entry : methodMap.entrySet()){
Object subscribeObject = entry.getValue().getSubscriberObject();
Method method = entry.getValue().getMethod();
try {
method.invoke(subscribeObject,object);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
这是我们最为主要的类,其中getInstance方法是一个单利模式,提供一个MyEventBus对象;register方法是注册方法,传入订阅者对象,该方法会调用findMethod方法,寻找有SubAnnotation注解的方法,并将类、调用者对象,方法放入一个map中;post方法是事件分发方法,遍历map中的所有对象,获取到订阅对象和方法,并使用invoke方法来调用该对象的该方法,完成事件分发过程。
2、Subscriber类
package jjy.jjyeventbus;
import java.lang.reflect.Method;
/**
* Created by JJY on 2017/3/26.
*/
public class Subscriber {
private Method method;
private Object subscriberObject;
public Subscriber(Method method, Object subscriberObject) {
this.method = method;
this.subscriberObject = subscriberObject;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public Object getSubscriberObject() {
return subscriberObject;
}
public void setSubscriberObject(Object subscriberObject) {
this.subscriberObject = subscriberObject;
}
}
package jjy.jjyeventbus;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by JJY on 2017/3/27.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SubAnnotation {
}
1、MyFragment类
package jjy.myeventbus;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import jjy.jjyeventbus.MyEventBus;
import jjy.jjyeventbus.SubAnnotation;
public class MyFragment extends Fragment {
private TextView textView;
public MyFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyEventBus.getInstance().register(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my, container, false);
textView = (TextView)view.findViewById(R.id.tv);
return view;
}
@SubAnnotation
public void abc(String msg){
textView.setText(msg);
}
}
方法abc为事件响应方法
2、MyFragment2类
package jjy.myeventbus;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import jjy.jjyeventbus.MyEventBus;
import jjy.jjyeventbus.SubAnnotation;
/**
* Created by JJY on 2017/3/27.
*/
public class MyFragment2 extends Fragment {
private TextView textView;
public MyFragment2() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyEventBus.getInstance().register(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my2, container, false);
textView = (TextView)view.findViewById(R.id.tv);
return view;
}
@SubAnnotation
public void fun(String msg){
textView.setText(msg);
}
}
方法fun为事件相应方法。
package jjy.myeventbus;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import jjy.jjyeventbus.MyEventBus;
public class MainActivity extends FragmentActivity{
private Button postbtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyEventBus.getInstance().register(this);
setContentView(R.layout.activity_main);
startService(new Intent(MainActivity.this,MyService.class));
postbtn = (Button)findViewById(R.id.postbtn);
postbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyEventBus.getInstance().post("MESSAGE!");
}
});
}
}
在Activity中分发事件。
截图: