There is no event bus library before

You can write interface callbacks and broadcast, but interacting with components such as activities and fragments can be a bit cumbersome, and the code is quite redundant!

After using the

The code is elegant, it relies on annotations, it keeps the code separate, it sends events when it needs to, and the specific methods that are annotated are called. In fact, Otto is similar to this library.

Begin to implement

Examples of usage

Bus.getdefault ().register(this); Event = new Event(); event.setUserId("111"); Bus.getDefault().post(event); @busReceiver public void onEvent(Event Event){system.out.println ("getEvent "+ event.getUserId()); } // Cancel the event library bus.getdefault ().unregister (this);Copy the code

Basically, the Api is similar to EventBus.

Custom annotations

 @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface BusReceiver {
    } Copy the code

The first version doesn’t take into account the event scheduling model, so the annotations are currently just code identifiers for internal processing.

Annotation processing

The basic idea

1 Register the event library

When registering the event library, you can get the @busReceiver annotation Method in the Activty and corresponding modification class, and create an mMethodMap (type Map<Object,List<Method>>) for later lookupCopy the code



2 Sending Events

At this point, the mMethodMap is iterated based on the event type, which is determined by calling method.invoke() to invoke a specific annotation method.Copy the code

Reflect is basically the API under use, such as get the class method, judgment annotation and processing operations!

code

public interface IBus { void register(Object target); void unRegister(Object target); void post(Object event); } public class Bus implements IBus {// 1 implements target; // 2 implements @busReceiver // map<targetType,eventType> // post to find the method set in the target of the eventType in the map and call the method private static Bus INSTANCE  = null; Private Map<Object,List<Method>> mMethodMap = new HashMap<>(); public static BusgetDefault() {if (INSTANCE == null){
                synchronized (Bus.class){
                    if(INSTANCE == null){ INSTANCE = new Bus(); }}}returnINSTANCE; } @override public void register(Object target) {List<Method> Override public void register(Object target) { annotatedMethods = Utils.findAnnotatedMethods(target.getClass(), BusReceiver.class); mMethodMap.put(target,annotatedMethods); } @Override public void unRegister(Object target) { mMethodMap.remove(target); } @Override public void post(Object event) { Class<? > eventClass = event.getClass(); // Methods in mMethodMap need to determine the event typefor (Map.Entry<Object, List<Method>> entry : mMethodMap.entrySet()) {
                Object target = entry.getKey();
                List<Method> methods = entry.getValue();
                if (methods == null || methods.isEmpty()){
                    continue;
                }
                for (Method method : methods) {
                    if (eventClass.equals(method.getParameterTypes()[0])){
                        try {
                            method.invoke(target,event);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }Copy the code

more 

The basic event-driven idea is like this, the change of ideas in exchange for clean code, especially in the case of App client events are more suitable to use a similar library, but there are still some shortcomings, continue to improve:

1 did not add scheduling and distribution model, specify methods in a particular thread callback;

2 method search efficiency problem, can be put into map cache, standard library JDK, Android SDK method can be skipped;

3 annotation processing efficiency problem, judge whether the order of conditions in line with the method can be adjusted;

4. The Method object can be abstracted appropriately.

Support for event inheritance has not been added yet.