打造一个炫酷的EventBus

来源:互联网 发布:剑网3成男捏脸数据 编辑:程序博客网 时间:2024/06/08 11:46

以前做了一个给EventBus增加消息提醒的Jar包,发现太丑了,而且我自己用久了之后看起来让我感觉很不爽。
很喜欢Logger的日志显示,所以仿照Logger重新打造了一下EventBus。
现在的效果如下
这里写图片描述
是不是感觉看起来很清爽,而且在哪里Post的或者哪里接收到的,点一下就可以进入Activity里面。

现在我们来开始打造:

首先,我们需要知道蓝色引导的Log怎么做。开始我以为是用的什么Java方法,在我反复测试之后,实际上它只是数据的形式,拼接好就有这个效果了。。。让我想起了知乎的一个主题《有哪些看起来高大上,实际上很简单的技巧》

格式:(JAVANAME:PAGE)

所以我这里是这样实现的

        postBuilder = new StringBuilder();        StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[4];        postBuilder.append(content_post)                .append("(")                .append(stackTraceElement.getFileName())                .append(":")                .append(stackTraceElement.getLineNumber())                .append(")");       //Log.e("tag",postBuilder.toString());

通过获取stack,得到调用的FileName和LineNumber,再拼接成这种格式,这里就有了蓝色的引导Log。
getStackTrace()[4]这里是我取了一个巧,得到调用的栈,以后会优化。

好了,接下来就开始完成我们的目标。

获取Post的信息

 public void post(Object event) {        //add the post activity info to logger        LoggerL.setPostMessage(event.getClass().getSimpleName());        ...

把Post的信息存入自己定义的Logger

在Invoke的时候把需要收到消息的Subscriber信息存入Logger

这里我是用了List<Map<String, String>>去存信息。

     public static void addSubscribe(String activity, String activityLog, String methodName, String eventType) {        Map<String, String> subscribeInfo = new HashMap<>();        subscribeInfo.put("activity", activity);        subscribeInfo.put("activityLog", activityLog);        subscribeInfo.put("methodName", methodName);        subscribeInfo.put(methodName, eventType);        subscribeList.add(subscribeInfo);    }

因为EventBus在注册的时候会把所有的Subscriber全部存入到subscriptionsByEventType里,方便通过JavaBean去找到subscriber然后Invoke,所以我们可以在register的时候取到我们所需要的信息–ActivityName(实际上应该是Subscriber所在的Java文件),JavaBeanName, MethodName,并存入自己的Logger

public void register(Object subscriber) {        Class<?> subscriberClass = subscriber.getClass();        //save register info to logger , so log can find the info when invoking        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);        StringBuilder postBuilder = new StringBuilder();        StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3];        postBuilder                .append("(")                .append(stackTraceElement.getFileName())                .append(":")                .append(stackTraceElement.getLineNumber())                .append(")");        synchronized (this) {            for (SubscriberMethod subscriberMethod : subscriberMethods) {                subscribe(subscriber, subscriberMethod);                //add all subscribe into Logger                LoggerL.addSubscribe(subscriberClass.getSimpleName(),postBuilder.toString(),subscriberMethod.method.getName(),subscriberMethod.eventType.getSimpleName());            }        }    }

别忘了在unregister的时候remove掉这些信息
in EventBus:

 public synchronized void unregister(Object subscriber) {        //remove the log info when unregister        LoggerL.removeSubscribe(subscriber.getClass().getSimpleName());          ...    }

in Logger:

 public static void removeSubscribe(String activity) {        for (Map<String, String> subscribe : subscribeList) {            if (activity.equals(subscribe.get("activity"))) {                subscribeList.remove(subscribe);                break;            }        }    }

Print信息

print肯定是在for循环的invoke下面调用,跟着源码往上看就找到了这样一个位置

   private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {        if (!subscriptionFound) {           ...        }        //print log        else{            LoggerL.print();        }    }

到现在为止基本上就完成了,剩下的就是修饰我们自己打印的Log了
这里是我仿照Logger的风格打印的

    private static final String line_top = "╔══════════════════════════════════════════════════════════════════════════════════════════════╗";    private static final String line_bottom = "╚══════════════════════════════════════════════════════════════════════════════════════════════╝";    private static final String line_part = "║----------------------------------------------------------------------------------------------║";    private static final String content_post = "║                                Post where : ";    private static final String content_event = "║                              Invoked ! EventType : ";    private static final String content_subscribe_where = "║            register : ";    private static final String content_subscribe_method = "method name : ";
public static void print() {        if (isDebug) {            Log.d(TAG, line_top);            Log.d(TAG, fixFormat(postBuilder.toString()));            Log.d(TAG, line_part);            Log.d(TAG, fixFormat(content_event + EventType));            Log.d(TAG, line_part);            for (Map<String, String> subscribeInfo : subscribeList) {                if (EventType.equals(subscribeInfo.get(subscribeInfo.get("methodName")))) {                    StringBuffer sb = new StringBuffer();                    sb.append(content_subscribe_where)                            .append(subscribeInfo.get("activityLog"))                            .append("     ")                            .append(content_subscribe_method)                            .append(subscribeInfo.get("methodName"))                            .append("()");                    Log.d(TAG, fixFormat(sb.toString()));                }            }            Log.d(TAG, line_bottom);        }    }

到此打造自己的EventBus完毕,其实很简单吧。

附上源码地址:https://github.com/adzcsx2/EventBusL

0 0
原创粉丝点击