自己实现一个简略版的EvnetBus

我们熟悉的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;
    }
}


3、SubAnnotation注解

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为事件相应方法。


3、MainActivity类

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中分发事件。


截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值