Understand EventBus and realize its basic functions

Understand EventBus and realize its basic functions

Basic usage of EventBus and understanding of each step:
Note: it is only the initial implementation of basic processes, viscous events and sub threads are not in the scope, only for self memory

1, Register to listen to EventBus.getDefault().register(this);

Save the class of the current page, all methods annotated by @ Subscribe and the parameters of this method to the cache for use
    /**
     * Register current class
     * @param object
     */
    public void register(Object object) {
        Class<?> aClass = object.getClass();
        /**Get all methods of the current class*/
        Method[] methods = aClass.getDeclaredMethods();
        SubEventBean subEventBean = new SubEventBean();
        ArrayList<SubEventBean.MethodAndEventBean> methodAndEventBeans = new ArrayList<>();
        for (Method method : methods) {
            SubEventBean.MethodAndEventBean methodAndEventBean = new SubEventBean.MethodAndEventBean();
            Subscribe annotation = method.getAnnotation(Subscribe.class);
            if (null != annotation) {
                Log.d(TAG, "event=========="+method.getName());
                /**Getting all the parameters of the current method is actually the Bean of the current subscription event*/
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (null != parameterTypes && parameterTypes.length == 1) {
                    Class<?> eventType = parameterTypes[0];//Events subscribed to by the current page
                    methodAndEventBean.setMethod(method);
                    methodAndEventBean.setEvent(eventType);
                    methodAndEventBeans.add(methodAndEventBean);
                }
            }
        }
        subEventBean.setMethods(methodAndEventBeans);
        /***Encapsulate registered class methods and event types into map for future use*/
        activity_subEvnt_map.put(object, subEventBean);
    } 

2, Send event EventBus.getDefault().post(demoBean);

Send the Event, obtain the class and method corresponding to the Event registration from the cache at the time of registration through the Event, and execute the method in the class using reflection

 /**
     * The main function of sending notification is to find the corresponding method and class in the previously registered class map through the sent event type and call them through reflection
     * @param obj
     */
    public void post(Object obj) {
        Class<?> aClass = obj.getClass();

        Set<Map.Entry<Object, SubEventBean>> activityEnts = activity_subEvnt_map.entrySet();
        for (Map.Entry<Object, SubEventBean> ent : activityEnts) {
            SubEventBean value = ent.getValue();
            List<SubEventBean.MethodAndEventBean> methods = value.getMethods();
            for (int i=0; i<methods.size(); i++) {
                SubEventBean.MethodAndEventBean methodAndEventBean = methods.get(i);
                Class<?> classes = methodAndEventBean.getEvent();
                if (classes.getName().equals(aClass.getName())) {
                    Object key = ent.getKey();
                    try {
                        methodAndEventBean.getMethod().invoke(key, obj);//Reflection trigger registration method
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }

                }

            }
        }

    }

3, Log off and listen to EventBus.getDefault().unregister(this);

Clear the data of this class in the cache before

 /**
     * Clear registered
     * @param obj
     */
    public void unregister(Object obj) {
        activity_subEvnt_map.remove(obj);

    }

Related classes

package com.example.XXX.myapplicationdemo.EventBus;

import android.util.Log;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by qf on 2018/7/18
 * Description: EventBus
 */
public class EventBus {

    private static final String TAG= "EventBus";

    static volatile EventBus eventBus;

    /**
     * Store subscription class details
     */
    public Map<Object, SubEventBean> activity_subEvnt_map = new LinkedHashMap<>();


    private EventBus(){
    }

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


    /**
     * Register current class
     * @param object
     */
    public void register(Object object) {
        Class<?> aClass = object.getClass();
        /**Get all methods of the current class*/
        Method[] methods = aClass.getDeclaredMethods();
        SubEventBean subEventBean = new SubEventBean();
        ArrayList<SubEventBean.MethodAndEventBean> methodAndEventBeans = new ArrayList<>();
        for (Method method : methods) {
            SubEventBean.MethodAndEventBean methodAndEventBean = new SubEventBean.MethodAndEventBean();
            Subscribe annotation = method.getAnnotation(Subscribe.class);
            if (null != annotation) {
                Log.d(TAG, "event=========="+method.getName());
                /**Getting all the parameters of the current method is actually the Bean of the current subscription event*/
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (null != parameterTypes && parameterTypes.length == 1) {
                    Class<?> eventType = parameterTypes[0];//Events subscribed by the current page
                    methodAndEventBean.setMethod(method);
                    methodAndEventBean.setEvent(eventType);
                    methodAndEventBeans.add(methodAndEventBean);
                }
            }
        }
        subEventBean.setMethods(methodAndEventBeans);
        /***Encapsulate registered class methods and event types into map for future use*/
        activity_subEvnt_map.put(object, subEventBean);
    }

    /**
     * The main function of sending notification is to find the corresponding method and class in the previously registered class map through the sent event type and call them through reflection
     * @param obj
     */
    public void post(Object obj) {
        Class<?> aClass = obj.getClass();

        Set<Map.Entry<Object, SubEventBean>> activityEnts = activity_subEvnt_map.entrySet();
        for (Map.Entry<Object, SubEventBean> ent : activityEnts) {
            SubEventBean value = ent.getValue();
            List<SubEventBean.MethodAndEventBean> methods = value.getMethods();
            for (int i=0; i<methods.size(); i++) {
                SubEventBean.MethodAndEventBean methodAndEventBean = methods.get(i);
                Class<?> classes = methodAndEventBean.getEvent();
                if (classes.getName().equals(aClass.getName())) {
                    Object key = ent.getKey();
                    try {
                        methodAndEventBean.getMethod().invoke(key, obj);//Reflection trigger registration method
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }

                }

            }
        }

    }

    /**
     * Clear registered
     * @param obj
     */
    public void unregister(Object obj) {
        activity_subEvnt_map.remove(obj);

    }

}
package com.example.XXXX.myapplicationdemo.EventBus;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by qf on 2018/7/18
 * Description: Subscribe
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
}
package com.example.XXXX.myapplicationdemo.EventBus;

import java.lang.reflect.Method;
import java.util.List;

/**
 * Created by qf on 2018/7/18
 * Description: SubEventBean
 */
public class SubEventBean {

    public Object subscribe;

    public List<MethodAndEventBean> methods;

    @Override
    public String toString() {
        return "SubEventBean{" +
                "subscribe=" + subscribe +
                ", methods=" + methods +
                '}';
    }

    public Object getSubscribe() {
        return subscribe;
    }

    public void setSubscribe(Object subscribe) {
        this.subscribe = subscribe;
    }

    public List<MethodAndEventBean> getMethods() {
        return methods;
    }

    public void setMethods(List<MethodAndEventBean> methods) {
        this.methods = methods;
    }

    public static class MethodAndEventBean {
        public Method method;

        public Class<?> Event;

        public Method getMethod() {
            return method;
        }

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

        public Class<?> getEvent() {
            return Event;
        }

        public void setEvent(Class<?> event) {
            Event = event;
        }

        @Override
        public String toString() {
            return "MethodAndEventBean{" +
                    "method=" + method +
                    ", Event=" + Event +
                    '}';
        }
    }
}

usage
Similar to the official version
1. Register EventBus.getEventBus().register(this);
2. Send event EventBus.getEventBus().post("this is a test");
3. Log out EventBus.getEventBus().unregister(this);

Tags: Java Android

Posted on Sun, 09 Feb 2020 07:05:31 -0800 by pahikua