感谢开源的魅力。开源很美。

  • SubscriberMethodFinder 发现注册方法类
  • SubscriberMethod 用户注册的方法组合
  • Subscription 用户和方法键值对应类
  • AsyncPoster 异步发起类
  • HandlerPoster 主线程发起类
  • PostBeen 消息类(发起类根据消息执行回调)
  • EventBus 访问类(建筑者模式)

**

注意!!!!!在onCreate 方法里面开启新线程一般默认为主线程,只有主线程空闲的时候才可以发起。Looper.myQueue().addIdleHandler

**

MainActivity



package com.lvshujun.customeventbus;


import com.lvshujun.event.EventBus;

import android.app.Activity;
import android.os.Bundle;
import android.os.Looper;
import android.os.MessageQueue.IdleHandler;


public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EventBus.getDefault().register(this);

        //EventBus.getDefault().unregister(this);
        Looper.myQueue().addIdleHandler(new IdleHandler() {

            @Override
            public boolean queueIdle() {
                // TODO Auto-generated method stub
                EventBus.getDefault().post(new ResponseEvent());
                return false;
            }
        });
    }

    public void onEventMainThread(ResponseEvent event)
    {
        System.out.println(Thread.currentThread().getName());
    }

}

SubscriberMethodFinder

package com.lvshujun.event;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;









public class SubscriberMethodFinder {

    private static final Map<String, List<SubscriberMethod>> methodCache = new HashMap<String, List<SubscriberMethod>>();

    List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        String cName = subscriberClass.getName();

        List<SubscriberMethod> subscriberMethods = null;

        synchronized (methodCache) {
             subscriberMethods = methodCache.get(cName);    
        }

        if(subscriberMethods != null)
            return subscriberMethods;

        subscriberMethods = new ArrayList<SubscriberMethod>();

        if(subscriberClass != null)
        {
            Method[] methods = subscriberClass.getDeclaredMethods();
            for(Method method:methods)
            {
                String methodName = method.getName();

                if(methodName.startsWith("onEvent"))
                {
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    if(parameterTypes.length == 1)
                    {
                        SubscriberMethod sm = new SubscriberMethod(method, parameterTypes[0]);
                        subscriberMethods.add(sm);
                    }
                }
            }
        }

        methodCache.put(cName, subscriberMethods);
        return subscriberMethods;
    }
}

Subscription

package com.lvshujun.event;



public final class Subscription {

    public final Object subscriber;
    public final SubscriberMethod subscriberMethod;




    Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
        this.subscriber = subscriber;
        this.subscriberMethod = subscriberMethod;

    }
}

SubscriberMethod

package com.lvshujun.event;

import java.lang.reflect.Method;



public final class SubscriberMethod {
    final public Method method;

    final public Class<?> eventType;



    SubscriberMethod(Method method, Class<?> eventType) {
        this.method = method;
        this.eventType = eventType;
    }


}

HandlerPoster

package com.lvshujun.event;

import java.util.LinkedList;

import java.util.Queue;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

final class HandlerPoster extends Handler {

    private Queue<PostBeen> queue;
    private final EventBus eventBus;

    HandlerPoster(EventBus eventBus, Looper looper) {
        super(looper);
        this.eventBus = eventBus;
        queue = new LinkedList<PostBeen>();
    }

    @Override
    public void handleMessage(Message msg) {

        try {

            PostBeen pendingPost = queue.poll();
            if (pendingPost == null) {

            } else {

                eventBus.invokeSubscriber(pendingPost);
            }

        } catch (Exception e) {
        } finally {

        }

    }

    void enqueue(Subscription subscription, Object event) {

        queue.add(new PostBeen(event, subscription));
        sendMessage(obtainMessage());
    }
}

AsyncPoster

package com.lvshujun.event;

import java.util.LinkedList;
import java.util.Queue;

public class AsyncPoster implements Runnable {

    private Queue<PostBeen> queue;
    private EventBus eventBus;

    public AsyncPoster(EventBus eventBus) {
        // super(looper);
        this.eventBus = eventBus;
        queue = new LinkedList<PostBeen>();
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {

            PostBeen pendingPost = queue.poll();
            if (pendingPost == null) {

            } else {

                eventBus.invokeSubscriber(pendingPost);
            }

        } catch (Exception e) {
        } finally {

        }
    }

    void enqueue(Subscription subscription, Object event) {

        queue.add(new PostBeen(event, subscription));
        eventBus.executorService.execute(this);
    }
}

PostBeen

package com.lvshujun.event;

public class PostBeen {

    public Object event;
    public Subscription subscription;
    public PostBeen(Object obj,Subscription sub)
    {
        this.event = obj;
        this.subscription = sub;
    }
}

EventBus

package com.lvshujun.event;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.os.Looper;

public class EventBus {

    private SubscriberMethodFinder methodFinder;
    ExecutorService executorService = Executors.newCachedThreadPool();

    private HandlerPoster handlerPoster;
    private AsyncPoster asyncPoster;
    private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
    private final Map<Object, List<Class<?>>> typesBySubscriber;
    public static EventBus single;

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

    public synchronized void register(Object subscriber) {
        List<SubscriberMethod> subscriberMethods = methodFinder.findSubscriberMethods(subscriber.getClass());
        for (SubscriberMethod method : subscriberMethods) {
            Class<?> eventType = method.eventType;
            CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
            Subscription newSubscription = new Subscription(subscriber, method);
            if (subscriptions == null) {
                subscriptions = new CopyOnWriteArrayList<Subscription>();
                subscriptionsByEventType.put(eventType, subscriptions);
            }
            subscriptions.add(newSubscription);

            List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
            if (subscribedEvents == null) {
                subscribedEvents = new ArrayList<Class<?>>();
                typesBySubscriber.put(subscriber, subscribedEvents);
            }
            subscribedEvents.add(eventType);
        }
    }

    public synchronized void unregister(Object subscriber) {
        List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
        if (subscribedTypes != null) {
            for (Class<?> eventType : subscribedTypes) {

                List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);

                if (subscriptions != null) {
                    int size = subscriptions.size();
                    for (int i = 0; i < size; i++) {
                        Subscription subscription = subscriptions.get(i);
                        if (subscription.subscriber == subscriber) {

                            System.out.println(subscription.subscriberMethod.method.getName());
                            subscriptions.remove(i);
                            i--;
                            size--;
                        }
                    }
                }

            }
            typesBySubscriber.remove(subscriber);
        }
    }

    public EventBus() {
        methodFinder = new SubscriberMethodFinder();
        subscriptionsByEventType = new HashMap<Class<?>, CopyOnWriteArrayList<Subscription>>();
        typesBySubscriber = new HashMap<Object, List<Class<?>>>();
        handlerPoster = new HandlerPoster(this, Looper.getMainLooper());
        asyncPoster = new AsyncPoster(this);
    }

    public void post(Object obj) {
        List<Subscription> subscriptions = subscriptionsByEventType.get(obj.getClass());
        if (subscriptions != null) {
            for (Subscription subscription : subscriptions)
            {
                System.out.println(subscription.subscriberMethod.method.getName());
                //handlerPoster.enqueue(subscription, obj);
                asyncPoster.enqueue(subscription, obj);
            }
        }
    }

    public void invokeSubscriber(PostBeen been)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Subscription sub = been.subscription;
        sub.subscriberMethod.method.invoke(sub.subscriber, been.event);
    }
}

下载地址 http://download.csdn.net/detail/q22232222/9063671

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐