感谢开源的魅力。开源很美。
- 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
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-25 18:24:45