以前做了一个给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完毕,其实很简单吧。