EventBus的使用及 解决异常 has no public methods called

来源:互联网 发布:计算机监控软件 编辑:程序博客网 时间:2024/05/16 13:46

平时一直使用EventBus这个组件,真的挺好用的,最近使用的时候偶尔出现错误就找了一下资料。

以下内容为转载,记录下来以后记不清楚了可以再回顾一下

EvenBus简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。它的效果和Handler的效果大致相同,但是实现原理和使用方法是完全不同的,它是基于保存相应方法,然后通过反射机制来实现的。更多的使用和原理,请参考:[Android EventBus实战](http://blog.csdn.net/jdsjlzx/article/details/40856535) 和[EventBus使用详解(二)——EventBus使用进阶](http://blog.csdn.net/harvic880925/article/details/40787203) ,他们会教会你怎样去使用EventBus,网上还有更多的教程,可以去搜索学习。

它是一个开源框架,可以在github上下载到:
https://github.com/greenrobot/EventBus

下载来后它的目录结构如下:
这里写图片描述

我们要使用EventBus只需将EventBus这个文件夹拷贝到我们的项目中,这样在我们的工程中就会出现两个包:
这里写图片描述

最后是我在第一次使用时出现的一个异常,或许初学者也会遇到的异常:
Subscriber ****has no public methods called
我们分析下为什么?
我这里先给出原因,个那些急忙解决的人:是因为在我们的类里使用了EventBus.getDefualt().register(this)了,但是在这个类里却没有定义一个以onEvent开头的、非静态的、public权限以及仅仅只有一个参数 的方法,也就是没有类似于:public void onEvent**(Object arg)这样的方法,导致出现了这个错误。

想要彻底知道为什么,请先查看EventBus的实现原理: Android EventBus源码解析 带你深入理解EventBus(http://blog.csdn.net/lmj623565791/article/details/40920453) 。
看完了这篇文章,你将会知道EventBus的实现原理,那么我们就再来看看这个异常发生的原因:
在de.greenrobot.event.SubscriberMethodFinder类里findSubscriberMethods()的方法,是在调用EventBus.getDefualt().register(this)后,经过层层调用,最后会调用到这个方法,

看源码:

List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {    ...    //获取clazz这个类的所有方法     Method[] methods = clazz.getDeclaredMethods();            for (Method method : methods) {                String methodName = method.getName();                if (methodName.startsWith(ON_EVENT_METHOD_NAME)) {                    int modifiers = method.getModifiers();                    //public的非静态的方法                    if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {                        Class<?>[] parameterTypes = method.getParameterTypes();                          //只有一个参数                        if (parameterTypes.length == 1) {                            String modifierString = methodName.substring(ON_EVENT_METHOD_NAME.length());                            ThreadMode threadMode;                            if (modifierString.length() == 0) {                                threadMode = ThreadMode.PostThread;                            } else if (modifierString.equals("MainThread")) {                                threadMode = ThreadMode.MainThread;                            } else if (modifierString.equals("BackgroundThread")) {                                threadMode = ThreadMode.BackgroundThread;                            } else if (modifierString.equals("Async")) {                                threadMode = ThreadMode.Async;                            } else {                                if (skipMethodVerificationForClasses.containsKey(clazz)) {                                    continue;                                } else {                                    throw new EventBusException("Illegal onEvent method, check for typos: " + method);                                }                            }                            Class<?> eventType = parameterTypes[0];                            methodKeyBuilder.setLength(0);                            methodKeyBuilder.append(methodName);                            methodKeyBuilder.append('>').append(eventType.getName());                            String methodKey = methodKeyBuilder.toString();                            if (eventTypesFound.add(methodKey)) {                                // Only add if not already found in a sub class                                subscriberMethods.add(new SubscriberMethod(method, threadMode, eventType));                            }                        }                    } else if (!skipMethodVerificationForClasses.containsKey(clazz)) {                        Log.d(EventBus.TAG, "Skipping method (not public, static or abstract): " + clazz + "."                                + methodName);                    }                }            }            clazz = clazz.getSuperclass();        }        //到此为查找目标对象(regiter(this)的this对象)中 onEvent开头的、非静态的、public权限以及仅仅只有一个参数 的方法,然后将这些方法放入到subscriberMethods中  if (subscriberMethods.isEmpty()) {            throw new EventBusException("Subscriber " + subscriberClass + " has no public methods called "                    + ON_EVENT_METHOD_NAME);        }       //看到没有,这就是这个异常抛出的地方,就是判断subscriberMethods如果是null,就抛出这个异常。....}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

好了,这个异常我们就分析到此,希望童鞋们能够很好的查找错误,分析错误,更好的去避免。通过源码是一个很好的方时。

0 0
原创粉丝点击