zoukankan      html  css  js  c++  java
  • EventBus的简单使用与原理

    EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。

    部分源码:

    //通过反射,获取到订阅者的所有方法
    			Method[] methods = clazz.getMethods();
    			for (Method method : methods) {
    				String methodName = method.getName();
    				//只找以onEvent开头的方法
    				if (methodName.startsWith(eventMethodName)) {
    					int modifiers = method.getModifiers();
    					//判断订阅者是否是public的,并且是否有修饰符,看来订阅者只能是public的,并且不能被final,static等修饰
    					if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
    						//获得订阅函数的参数
    						Class<?>[] parameterTypes = method.getParameterTypes();
    						//看了参数的个数只能是1个
    						if (parameterTypes.length == 1) {
    							//获取onEvent后面的部分
    							String modifierString = methodName.substring(eventMethodName.length());
    							ThreadMode threadMode;
    							if (modifierString.length() == 0) {
    								//订阅函数为onEvnet
    								//记录线程模型为PostThread,意义就是发布事件和接收事件在同一个线程执行,详细可以参考我对于四个订阅函数不同点分析
    								threadMode = ThreadMode.PostThread;
    							} else if (modifierString.equals("MainThread")) {
    								//对应onEventMainThread
    								threadMode = ThreadMode.MainThread;
    							} else if (modifierString.equals("BackgroundThread")) {
    								//对应onEventBackgrondThread
    								threadMode = ThreadMode.BackgroundThread;
    							} else if (modifierString.equals("Async")) {
    								//对应onEventAsync
    								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
    								//封装一个订阅方法对象,这个对象包含Method对象,threadMode对象,eventType对象
    								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();
    		}
    		//最后加入缓存,第二次使用直接从缓存拿
    		if (subscriberMethods.isEmpty()) {
    			throw new EventBusException("Subscriber " + subscriberClass + " has no public methods called "
    					+ eventMethodName);
    		} else {
    			synchronized (methodCache) {
    				methodCache.put(key, subscriberMethods);
    			}
    			return subscriberMethods;
    		}
    	}

    更多源码见:http://www.tuicool.com/articles/jUvyUjB

  • 相关阅读:
    cliconfg
    SQL 校验身份证格式
    常用MIME类型汇总
    SqlBulkCopy批量将Excel(Aspose)数据导入至SQL Server
    C#生成图片验证码
    SqlServer PIVOT函数快速实现行转列,UNPIVOT实现列转行
    SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别
    C#常用加密方式
    CURSOR 游标使用示例
    linux命令
  • 原文地址:https://www.cnblogs.com/czh-/p/5992638.html
Copyright © 2011-2022 走看看