AndroidUtil - 极简EventBus - 结合map,handler和线程池

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Publish/Subscribe
 */
public class EventBus {

    private static final String TAG = "EventBus";

    /**
     * 子线程
     */
    public static final int THREAD_SUB = 0;

    /**
     * 当前线程
     */
    public static final int THREAD_CURRENT = 1;

    /**
     * 主线程
     */
    public static final int THREAD_MAIN = 2;

    private static final int EXECUTOR_POOL_SIZE = 1;

    private static final HashMap<String, EventBus> BUS = new HashMap<String, EventBus>();

    private static final ReentrantLock lock = new ReentrantLock();

    private static ExecutorService EXECUTOR = null;

    /**
     * 事件回调
     */
    public interface ICallback {
        void onEvent(Event event);
    }

    /**
     * 事件
     */
    public static class Event {

        private String action;

        private Bundle bundle;

        public Event(String action) {
            this.action = action;
            bundle = new Bundle();
        }

        public String getAction() {
            return action;
        }

        public Bundle getBundle() {
            return bundle;
        }
    }

    private ArrayList<CallbackHandler> handlers = new ArrayList<CallbackHandler>();

    private EventBus() {
    }

    /**
     * 发布
     *
     * @param event
     */
    public static void publish(Event event) {
        if(null == event){
            return;
        }
        String action = event.action;
        if (action == null) {
            return;
        }

        lock.lock();
        try {
            EventBus bus = BUS.get(action);
            if (bus != null) {
                ArrayList<CallbackHandler> handlers = bus.handlers;
                for (CallbackHandler handler : handlers) {
                    handler.post(event);
                }
            }
        } finally {
            lock.unlock();
        }
    }

    /**
     * 订阅
     *
     * @param callback 接收到事件后执行的回调
     * @param thread   执行回调所在的线程,取值为THREAD_SUB、THREAD_CURRENT、THREAD_MAIN
     * @param actions  订阅的事件类型
     */
    public static void subscribe(ICallback callback, int thread, String... actions) {
        if (callback == null || actions == null || actions.length == 0) {
            return;
        }

        lock.lock();
        try {
            CallbackHandler handlerToAdd = null;
            for (String action : actions) {
                if (action == null) {
                    continue;
                }

                EventBus bus = BUS.get(action);
                if (bus == null) {
                    bus = new EventBus();
                    BUS.put(action, bus);
                }

                ArrayList<CallbackHandler> handlers = bus.handlers;
                boolean added = false;
                for (CallbackHandler handler : handlers) {
                    if (handler.callback == callback) {
                        added = true;
                        break;
                    }
                }
                if (!added) {
                    if (handlerToAdd == null) {
                        handlerToAdd = new CallbackHandler(callback, thread);
                    }
                    handlers.add(handlerToAdd);
                }
            }
        } finally {
            lock.unlock();
        }
    }

    /**
     * 取消订阅
     *
     * @param callback
     * @param actions  取消订阅的事件类型
     */
    public static void unsubscribe(ICallback callback, String... actions) {
        if (callback == null || actions == null || actions.length == 0) {
            return;
        }

        lock.lock();
        try {
            for (String action : actions) {
                if (action == null) {
                    continue;
                }

                EventBus bus = BUS.get(action);
                if (bus == null) {
                    continue;
                }

                ArrayList<CallbackHandler> handlers = bus.handlers;
                int index = 0;
                int size = handlers.size();
                for (; index < size; index++) {
                    if (handlers.get(index).callback == callback) {
                        break;
                    }
                }
                if (index < size) {
                    handlers.remove(index);
                    if (handlers.isEmpty()) {
                        BUS.remove(action);
                        if (BUS.isEmpty() && EXECUTOR != null) {
                            EXECUTOR.shutdown();
                            EXECUTOR = null;
                        }
                    }
                }
            }
        } finally {
            lock.unlock();
        }
    }

    private static class CallbackHandler {

        ICallback callback;

        Handler handler;

        CallbackHandler(ICallback callback, int thread) {
            this.callback = callback;

            if (thread == THREAD_CURRENT) {
                Looper looper = Looper.myLooper();
                if (looper == null) {
                    throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
                }
                handler = new Handler(looper);
            } else if (thread == THREAD_MAIN) {
                handler = new Handler(Looper.getMainLooper());
            } else {
                // 默认使用子线程
                handler = null;
            }
        }

        void post(final Event event) {
            Runnable runable = new Runnable() {
                @Override
                public void run() {
                    long t0 = System.currentTimeMillis();
                    try {
                        callback.onEvent(event);
                    } finally {
                        // 如果子线程中的回调执行时间太长,给出提示
                        if (handler == null) {
                            long t = System.currentTimeMillis() - t0;
                            if (t > 5 * 1000) {
                                LogUtil.d(true,TAG, callback.getClass().getName(), " takes too long (", t, "ms)!");
                            }
                        }
                    }
                }
            };

            if (handler != null) {
                handler.post(runable);
            } else {
                if (EXECUTOR == null) {
                    EXECUTOR = Executors.newFixedThreadPool(EXECUTOR_POOL_SIZE);
                }
                EXECUTOR.execute(runable);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_16206535/article/details/79448280