打造一个炫酷的EventBus

以前做了一个给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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值