/*
* Copyright (C) 2012 Square, Inc.
* Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.otto;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* Dispatches events to listeners, and provides ways for listeners to register themselves.
* <p>
* <p>The Bus allows publish-subscribe-style communication between components without requiring the components to
* explicitly register with one another (and thus be aware of each other). It is designed exclusively to replace
* traditional Android in-process event distribution using explicit registration or listeners. It is <em>not</em> a
* general-purpose publish-subscribe system, nor is it intended for interprocess communication.
* <p>
* <h2>Receiving Events</h2>
* To receive events, an object should:
* <ol>
* <li>Expose a public method, known as the <i>event handler</i>, which accepts a single argument of the type of event
* desired;</li>
* <li>Mark it with a {@link com.squareup.otto.Subscribe} annotation;</li>
* <li>Pass itself to an Bus instance's {@link #register(Object)} method.
* </li>
* </ol>
* <p>
* <h2>Posting Events</h2>
* To post an event, simply provide the event object to the {@link #post(Object)} method. The Bus instance will
* determine the type of event and route it to all registered listeners.
* <p>
* <p>Events are routed based on their type — an event will be delivered to any handler for any type to which the
* event is <em>assignable.</em> This includes implemented interfaces, all superclasses, and all interfaces implemented
* by superclasses.
* <p>
* <p>When {@code post} is called, all registered handlers for an event are run in sequence, so handlers should be
* reasonably quick. If an event may trigger an extended process (such as a database load), spawn a thread or queue it
* for later.
* <p>
* <h2>Handler Methods</h2>
* Event handler methods must accept only one argument: the event.
* <p>
* <p>Handlers should not, in general, throw. If they do, the Bus will wrap the exception and
* re-throw it.
* <p>
* <p>The Bus by default enforces that all interactions occur on the main thread. You can provide an alternate
* enforcement by passing a {@link ThreadEnforcer} to the constructor.
* <p>
* <h2>Producer Methods</h2>
* Producer methods should accept no arguments and return their event type. When a subscriber is registered for a type
* that a producer is also already registered for, the subscriber will be called with the return value from the
* producer.
* <p>
* <h2>Dead Events</h2>
* If an event is posted, but no registered handlers can accept it, it is considered "dead." To give the system a
* second chance to handle dead events, they are wrapped in an instance of {@link com.squareup.otto.DeadEvent} and
* reposted.
* <p>
* <p>This class is safe for concurrent use.
*
* @author Cliff Biffle
* @author Jake Wharton
*/
public class Bus {
public static final String DEFAULT_IDENTIFIER = "default";
/**
* 订阅方法集合:ConcurrentMap<事件类型, 该事件的订阅方法集合>
*/
private final ConcurrentMap<Class<?>, Set<EventHandler>> handlersByType =
new ConcurrentHashMap<Class<?>, Set<EventHandler>>();
/**
* 生成事件的方法集合:ConcurrentMap<事件类型, 该事件生成方法>
*
* @Note Produce注解生成的事件方法,一个事件只能定义一个方法,不能重复定义。否则会抛出异常
* 原因参见AnnotatedHandlerFinder类中loadAnnotatedMethods 会检查是否已有该事件的@Produce方法。
*/
private final ConcurrentMap<Class<?>, EventProducer> producersByType =
new ConcurrentHashMap<Class<?>, EventProducer>();
/**
* Identifier used to differentiate the event bus instance.
*/
private final String identifier; //当前Bus实例的名称
/**
* Thread enforcer for register, unregister, and posting events.
*/
private final ThreadEnforcer enforcer;//线程检查,默认ThreadEnforcer.MAIN
/**
* 负责从类中查找@Suscribe和@Produce的方法
*/
private final HandlerFinder handlerFinder; //默认为 HandlerFinder.ANNOTATED
/**
* 当前线程发送的事件队列
*/
private final ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>> eventsToDispatch =
new ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>>() {
@Override
protected ConcurrentLinkedQueue<EventWithHandler> initialValue() {
return new ConcurrentLinkedQueue<EventWithHandler>();
}
};
/**
* 当前线程是否正在发送事件
*/
private final ThreadLocal<Boolean> isDispatching = new ThreadLocal<Boolean>() {
@Override
protected Boolean initialValue() {
return false;
}
};
/**
* Creates a new Bus named "default" that enforces actions on the main thread.
*/
public Bus() {
this(DEFAULT_IDENTIFIER);
}
public Bus(String identifier) {
this(ThreadEnforcer.MAIN, identifier);
}
public Bus(ThreadEnforcer enforcer) {
this(enforcer, DEFAULT_IDENTIFIER);
}
public Bus(ThreadEnforcer enforcer, String identifier) {
this(enforcer, identifier, HandlerFinder.ANNOTATED);
}
Bus(ThreadEnforcer enforcer, String identifier, HandlerFinder handlerFinder) {
this.enforcer = enforcer;
this.identifier = identifier;
this.handlerFinder = handlerFinder;
}
@Override
public String toString() {
return "[Bus \"" + identifier + "\"]";
}
/**
* 注册事件
* 查找类中所有的@Subscribe和@Produce方法
* 1)如果当前类中存在@Produce方法,则检查是否订阅了该事件类型的订阅方法,存在则生成事件对象并发送事件。
* 2)对于订阅方法,检查这些订阅方法的事件类型是否存在@Produce,存在的话,则调用Producer生成事件对象发送事件。
*/
public void register(Object object) {
if (object == null) {
throw new NullPointerException("Object to register must not be null.");
}
//检查线程 否则抛出异常
enforcer.enforce(this); //默认在主线程
//查询类中所有@Produce的方法
Map<Class<?>, EventProducer> foundProducers = handlerFinder.findAllProducers(object);
for (Class<?> type : foundProducers.keySet()) {
final EventProducer producer = foundProducers.get(type);
EventProducer previousProducer = producersByType.putIfAbsent(type, producer);
//checking if the previous producer existed
if (previousProducer != null) {
throw new IllegalArgumentException("Producer method for type " + type
+ "
没有合适的资源?快使用搜索试试~ 我知道了~
Otto源码及Demo
共59个文件
java:21个
xml:12个
png:8个
需积分: 9 11 下载量 108 浏览量
2016-10-19
14:26:32
上传
评论
收藏 151KB ZIP 举报
温馨提示
Otto源码分析,使用Demo
资源推荐
资源详情
资源评论
收起资源包目录
Otto.zip (59个子文件)
Otto
gradlew 5KB
settings.gradle 28B
library
src
main
AndroidManifest.xml 276B
res
drawable
values
strings.xml 73B
java
com
squareup
otto
AnnotatedHandlerFinder.java 9KB
ThreadEnforcer.java 2KB
Produce.java 1KB
Bus.java 18KB
HandlerFinder.java 1KB
Subscribe.java 1KB
EventProducer.java 3KB
EventHandler.java 4KB
DeadEvent.java 1KB
library.iml 9KB
libs
.gitignore 8B
build.gradle 596B
proguard-rules.pro 688B
gradle
wrapper
gradle-wrapper.properties 239B
gradle-wrapper.jar 52KB
local.properties 475B
gradlew.bat 2KB
Otto-demo.iml 963B
gradle.properties 872B
.gitignore 105B
app
src
main
AndroidManifest.xml 1KB
res
mipmap-hdpi
ic_launcher.png 3KB
mipmap-xxxhdpi
ic_launcher.png 10KB
mipmap-xhdpi
ic_launcher.png 5KB
drawable-hdpi
icon.png 9KB
mipmap-mdpi
ic_launcher.png 2KB
drawable
drawable-mdpi
icon.png 6KB
layout
two_act.xml 639B
location_history.xml 2KB
first_act.xml 439B
drawable-xhdpi
icon.png 12KB
values-w820dp
dimens.xml 364B
values
colors.xml 214B
strings.xml 190B
styles.xml 394B
dimens.xml 65B
mipmap-xxhdpi
ic_launcher.png 8KB
layout-land
location_history.xml 2KB
java
com
squareup
otto
sample
LocationChangedEvent.java 1KB
LocationClearEvent.java 688B
LocationHistoryFragment.java 2KB
test
TwoActivity.java 2KB
BaseActivity.java 709B
EventInterface.java 103B
BaseEvent.java 246B
PushEvent.java 202B
FirstActivity.java 1KB
LocationActivity.java 3KB
BusProvider.java 1KB
LocationMapFragment.java 3KB
libs
app.iml 9KB
.gitignore 8B
build.gradle 670B
proguard-rules.pro 688B
build.gradle 521B
共 59 条
- 1
资源评论
zhangquanit
- 粉丝: 24
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功