Android eventbus开源框架(模仿)

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

  • 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

Android eventbus开源框架(模仿)的相关文章

android AsyncHttpClient 开源框架的使用

AsyncHttpClient 1.在很多时候android都需要进行网络的操作,而android自带的HttpClient可以实现,但要进行很多网络连接的时候(如:下载很多图片),就需要线程池来进行管理,但默认都是阻塞式操作.这种模型效率不高,对并发要求高的 APP 来讲,并不适用,要用AsyncHttpClient 就必须下载一个jar包   ------>>  下载地址. 2.AsyncHttpClient框架是异步的框架,而且已经封装好了了线程池的操作.所以对网络的操作都是很快的! 3

25类Android常用开源框架

1.图片加载,缓存,处理 框架名称 功能描述 Android Universal Image Loader 一个强大的加载,缓存,展示图片的库,已过时 Picasso 一个强大的图片下载与缓存的库 Fresco 一个用于管理图像和他们使用的内存的库 Glide 一个图片加载和缓存的库,使用的App有:网易新闻 GlidePalette Android Lollipop Palette is now easy to use with Glide PicassoPalette Android Lol

【转载】android 常用开源框架

对于Android初学者以及对于我们菜鸟,这些大神们开发的轻量级框架非常有用(更别说开源的了). 下面转载这10个框架的介绍:(按顺序来吧没有什么排名). 一.  Afinal 官方介绍: Afinal是一个android的ioc,orm框架,内置了四大模块功能:FinalAcitivity,FinalBitmap,FinalDb,FinalHttp. 通过finalActivity,我们可以通过注解的方式进行绑定ui和事件. 通过finalBitmap,我们可以方便的加载bitmap图片,而无

Android使用开源框架加载图片

Android开发时,有时候需要们来加载网络图片,我们可以通过api的方式进行加载,但是前几天做的时候,发现了一个优秀的开源框架,可以帮助我们非常简单便捷的进行图片的加载,所以记录一下. 我所用的是: android-smart-image-view 在github上的地址是:https://github.com/loopj/android-smart-image-view,我们可以直接进行搜索,github对于我们程序员来说简直是宝库啊,一定要能够擅长应用. 下载下来后,我们把其目录下的src

Android UI开源框架

1.Side-Menu.Android 分类侧滑菜单,Yalantis 出品. 项目地址:https://github.com/Yalantis/Side-Menu.Android 2.Context-Menu.Android 可以方便快速集成漂亮带有动画效果的上下文菜单,Yalantis出品. 项目地址:https://github.com/Yalantis/Context-Menu.Android 3.Pull-to-Refresh.Rentals-Android 提供一个简单可以自定义的下

Android RoboGuice开源框架、Butter Knife开源框架浅析

Google Guice on Android(RoboGuice) 今天介绍一下Google的这个开源框架RoboGuice, 它的作用跟之前讲过的Dagger框架差点儿是一样的,仅仅是Dagger比它的功能更强大一些. Dagger通过专注于一种简化的功能集以一种不同的方式达到了更好的性能.有人觉得RoboGuice节约了大量的时间.较少的代码意味着较少的错误.较少的样板代码意味着能够把很多其它的时间放到应用的核心逻辑上.所以这就是为什么我们要使用这些开源框架来开发的原因. 以下我们来说说R

Android第三方开源框架之SlidingMenu详解 [转载]

SlidingMenu简介:       SlidingMenu的是一种比较新的设置界面或配置界面效果,在主界面左滑或者右滑出现设置界面,能方便的进行各种操作.目前有大量的应用都在使用这一效果.如Evernote.Google+.Foursquare等,国内的豌豆夹,人人,360手机助手等都使用SlidingMenu的界面方案. 开源框架下载地址,集成了另一个开源项目ActionBarSherlock:点击下载.              注意: SlidingMenu依赖于另一个开源项目Act

Android roboguice 开源框架使用

Android roboguice 应用 开源的roboguice是一个依赖注入框架,如果你用过Spring 应该知道其好处. 减少程序员的负担,代码变的更加简洁. 地址:https://github.com/roboguice/roboguice 工具用的是Android Studio 因为Gradle可以自动添加第三方库. Gradle部分内容: dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile

EventBus开源框架的使用与解析

一.概述 前一篇给大家装简单演示了EventBus的onEventMainThread()函数的接收,其实EventBus还有另外有个不同的函数,他们分别是: 1.onEvent 2.onEventMainThread 3.onEventBackgroundThread 4.onEventAsync 这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念: 告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发