一、EventBus
EventBus使用了发布者/订阅者模式,简化组件间通讯,解耦事件的发送方和接收方
1、注册register
public void register(Object subscriber) {
//以订阅者 class 为入口
Class<?> subscriberClass = subscriber.getClass();
//获取订阅者 class 所有订阅 method
//内部有缓存 METHOD_CACHE,ConcurrentHashMap<Class<?>,List<SubscriberMethod>>
//通过反射获取 Method 的参数类型 eventType、注解 ThreadMode 等
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
//订阅者订阅每个事件方法
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
// Must be called in synchronized block
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//事件类型
Class<?> eventType = subscriberMethod.eventType;
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//根据事件类型获取所有订阅者
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
//遍历所有订阅者,根据优先级插入集合
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
//获取该订阅者的所有事件类型集合,并添加新的事件类型
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);
//处理粘性事件
if (subscriberMethod.sticky) {
if (eventInheritance) {
// Existing sticky events of all subclasses of eventType have to be considered.
// Note: Iterating over all events may be inefficient with lots of sticky events,
// thus data structure should be changed to allow a more efficient lookup
// (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
for (Map.Entry<Class<?>, Object> entry : entries) {
Class<?> candidateEventType = entry.getKey();
if (eventType.isAssignableFrom(candidateEventType)) {
Object stickyEvent = entry.getValue();
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
//stickyEvents存储粘性事件
Object stickyEvent = stickyEvents.get(eventType);
//检查是否有粘性事件并执行
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
if (stickyEvent != null) {
// If the subscriber is trying to abort the event, it will fail (event is not tracked in posting state)
// --> Strange corner case, which we don't take care of here.
postToSubscription(newSubscription, stickyEvent, isMainThread());
}
}
2、发送post
public void post(Object event) {
//获取当前线程PostingThreadState
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
//放入当前线程事件队列
eventQueue.add(event);
if (!postingState.isPosting) {
postingState.isMainThread = isMainThread();
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
//不停取出事件,发送
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
//事件类型
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
if (eventInheritance) {
//查找所有该evenClass的父类和接口
List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
int countTypes = eventTypes.size();
//遍历发送单个事件
for (int h = 0; h < countTypes; h++) {
Class<?> clazz = eventTypes.get(h);
subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
}
} else {
subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
}
if (!subscriptionFound) {
if (logNoSubscriberMessages) {
logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
}
}
}
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
//根据事件类型获取所有订阅者,register时已处理订阅者优先级
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted;
try {
//发送事件给每个订阅者
postToSubscription(subscription, event, postingState.isMainThread);
aborted = postingState.canceled;
} finally {
postingState.event = null;
postingState.subscription = null;
postingState.canceled = false;
}
if (aborted) {
break;
}
}
return true;
}
return false;
}
3、发送postSticky
public void postSticky(Object event) {
synchronized (stickyEvents) {
//保存粘性事件,register时会检查
stickyEvents.put(event.getClass(), event);
}
// Should be posted after it is putted, in case the subscriber wants to remove immediately
post(event); //发送事件
}
4、注销unregister
public synchronized void unregister(Object subscriber) {
//获取该订阅者的所有事件类型
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class<?> eventType : subscribedTypes) {
//移除该订阅者每个事件类型
unsubscribeByEventType(subscriber, eventType);
}
//移除该订阅者
typesBySubscriber.remove(subscriber);
} else {
logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
//获取所有该事件类型订阅者
List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
for (int i = 0; i < size; i++) {
Subscription subscription = subscriptions.get(i);
if (subscription.subscriber == subscriber) {
subscription.active = false;
//移除该订阅者
subscriptions.remove(i);
i--;
size--;
}
}
}
}
5、ThreadMode
控制订阅者执行的线程
@Subscribe(threadMode = ThreadMode.POSTING)
POSTING:默认,在发布事件的同一线程中直接执行MAIN:Android的主线程,如果发布事件是主线程,直接执行,否则排队执行MAIN_ORDERED:与MAIN不同,事件将排队,确保了post调用是非阻塞的BACKGROUND:后台线程,如果发布事件线程不是主线程,直接执行,如果是主线程,则使用线程池单个线程顺序执行所有事件ASYNC:不管发布事件的线程,使用EventBus线程池执行(newCachedThreadPool)
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
case POSTING:
invokeSubscriber(subscription, event);
break;
case MAIN:
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
//内部使用HandlerPoster,HandlerPoster继承Handler,传入mainLooper
//enqueue方法将事件放入队列,并调用sendMessage
//handleMessage中死循环取事件,调用invokeSubscriber执行
mainThreadPoster.enqueue(subscription, event);
}
break;
case MAIN_ORDERED:
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
// temporary: technically not correct as poster not decoupled from subscriber
invokeSubscriber(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
//BackgroundPoster实现Runnable接口
//enqueue方法中将事件放入队列,并获取eventBus的executorService线程池,传入自己
//run方法中死循环取事件,调用invokeSubscriber执行
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
//AsyncPoster实现Runnable接口
//enqueue方法中将事件放入队列,并获取eventBus的executorService线程池,传入自己
//run方法中取事件,调用invokeSubscriber执行
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
//eventBus的executorService线程池使用newCachedThreadPool创建
//BackgroundPoster使用线程池中的一个线程执行队列任务
//AsyncPoster直接将任务放入线程池,使用多个线程执行
二、OKHttp3
1、OkHttpClient初始化
OkHttpClient是核心管理类,通过Builder构造器生成,构造参数和类成员很多
//无参构造 OkHttpClient(),调用重载方法
//Builder()中会初始化 dispatcher、connectionPool 等必要
constructor() : this(Builder())
open class OkHttpClient internal constructor(builder: Builder) : Cloneable, Call.Factory, WebSocket.Factory
2、okHttpClient.newCall
RealCall包装了okHttpClient和request,并负责请求的调度和责任链的构造
override fun newCall(request: Request): Call = RealCall(this, request, forWebSocket = false)
class RealCall(
val client: OkHttpClient,
/** The application's original request unadulterated by redirects or auth headers. */
val originalRequest: Request,
val forWebSocket: Boolean
) : Call
// RealCall 实现了 Call 接口,Call接口中有 execute、enqueue 等方法需要实现
3、执行execute & enqueue
override fun execute(): Response {
check(executed.compareAndSet(false, true)) { "Already Executed" }
timeout.enter()
callStart()
try {
//调用 dispatcher.executed
client.dispatcher.executed(this)
//真正开始请求
return getResponseWithInterceptorChain()
} finally {
//调度器请求结束,会再次调用promoteAndExecute()触发执行检查
client.dispatcher.finished(this)
}
}
//dispatcher 仅添加到 ArrayDeque 中
@Synchronized internal fun executed(call: RealCall) {
runningSyncCalls.add(call)
}
override fun enqueue(responseCallback: Callback) {
check(executed.compareAndSet(false, true)) { "Already Executed" }
callStart()
//调用 dispatcher.enqueue,并包装成AsyncCall
//AsyncCall 实现了 Runnable 接口
client.dispatcher.enqueue(AsyncCall(responseCallback))
}
internal fun enqueue(call: AsyncCall) {
synchronized(this) {
//放入readyAsyncCalls
readyAsyncCalls.add(call)
// Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
// the same host.
if (!call.call.forWebSocket) {
val existingCall = findExistingCallWithHost(call.host)
if (existingCall != null) call.reuseCallsPerHostFrom(existingCall)
}
}
promoteAndExecute() //触发执行检查
}
// Dispatcher
private fun promoteAndExecute(): Boolean {
this.assertThreadDoesntHoldLock()
val executableCalls = mutableListOf<AsyncCall>()
val isRunning: Boolean
synchronized(this) {
val i = readyAsyncCalls.iterator()
while (i.hasNext()) {
val asyncCall = i.next()
//超过最大请求数
if (runningAsyncCalls.size >= this.maxRequests) break // Max capacity.
//每个host最大请求数
if (asyncCall.callsPerHost.get() >= this.maxRequestsPerHost) continue // Host max capacity.
i.remove() //符合要求,从readyAsyncCalls删除
asyncCall.callsPerHost.incrementAndGet() //该host数加1
executableCalls.add(asyncCall) //添加到可执行集合
runningAsyncCalls.add(asyncCall) //添加到执行中集合
}
isRunning = runningCallsCount() > 0
}
for (i in 0 until executableCalls.size) {
val asyncCall = executableCalls[i]
asyncCall.executeOn(executorService) //调用执行,传入线程池
}
return isRunning
}
// RealCall.AsyncCall
fun executeOn(executorService: ExecutorService) {
client.dispatcher.assertThreadDoesntHoldLock()
var success = false
try {
//放入线程池中,等待执行 AsyncCall 的 run 方法
executorService.execute(this)
success = true
} catch (e: RejectedExecutionException) {
val ioException = InterruptedIOException("executor rejected")
ioException.initCause(e)
noMoreExchanges(ioException)
responseCallback.onFailure(this@RealCall, ioException)
} finally {
if (!success) {
client.dispatcher.finished(this) // This call is no longer running!
}
}
}
// RealCall.AsyncCall.run()
override fun run() {
threadName("OkHttp ${redactedUrl()}") {
var signalledCallback = false
timeout.enter()
try {
//真正开始请求
val response = getResponseWithInterceptorChain()
signalledCallback = true
responseCallback.onResponse(this@RealCall, response)
} catch (e: IOException) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log("Callback failure for ${toLoggableString()}", Platform.INFO, e)
} else {
responseCallback.onFailure(this@RealCall, e)
}
} catch (t: Throwable) {
cancel()
if (!signalledCallback) {
val canceledException = IOException("canceled due to $t")
canceledException.addSuppressed(t)
responseCallback.onFailure(this@RealCall, canceledException)
}
throw t
} finally {
//调度器请求结束,会再次调用promoteAndExecute()触发执行检查
client.dispatcher.finished(this)
}
}
}
4、拦截器
拦截器是OKHttp的核心,OKHttp将整个请求的复杂逻辑切成了一个一个的独立模块并命名为拦截器(Interceptor),通过责任链的设计模式串联到了一起,最终完成请求获取响应结果
RetryAndFollowUpInterceptor:失败和重定向拦截器BridgeInterceptor:封装request和response的拦截器CacheInterceptor:缓存拦截器,负责读取缓存返回、更新缓存ConnectInterceptor:连接拦截器,负责和服务器建立连接CallServerInterceptor:负责向服务端发送请求数据,从服务端读取响应数据,进行http请求报文的封装和请求报文的解析
//RealCall
@Throws(IOException::class)
internal fun getResponseWithInterceptorChain(): Response {
// Build a full stack of interceptors.
val interceptors = mutableListOf<Interceptor>()
interceptors += client.interceptors
interceptors += RetryAndFollowUpInterceptor(client)
interceptors += BridgeInterceptor(client.cookieJar)
interceptors += CacheInterceptor(client.cache)
interceptors += ConnectInterceptor //连接连接器,真正开始请求
if (!forWebSocket) {
interceptors += client.networkInterceptors
}
interceptors += CallServerInterceptor(forWebSocket)
//创建责任链
val chain = RealInterceptorChain(
call = this,
interceptors = interceptors,
index = 0,
exchange = null,
request = originalRequest,
connectTimeoutMillis = client.connectTimeoutMillis,
readTimeoutMillis = client.readTimeoutMillis,
writeTimeoutMillis = client.writeTimeoutMillis
)
var calledNoMoreExchanges = false
try {
val response = chain.proceed(originalRequest) //执行
if (isCanceled()) {
response.closeQuietly()
throw IOException("Canceled")
}
return response
} catch (e: IOException) {
calledNoMoreExchanges = true
throw noMoreExchanges(e) as Throwable
} finally {
if (!calledNoMoreExchanges) {
noMoreExchanges(null)
}
}
}
//RealInterceptorChain
override fun proceed(request: Request): Response {
check(index < interceptors.size)
calls++
if (exchange != null) {
check(exchange.finder.sameHostAndPort(request.url)) {
"network interceptor ${interceptors[index - 1]} must retain the same host and port"
}
check(calls == 1) {
"network interceptor ${interceptors[index - 1]} must call proceed() exactly once"
}
}
// Call the next interceptor in the chain.
val next = copy(index = index + 1, request = request) //下一个拦截器
val interceptor = interceptors[index]
@Suppress("USELESS_ELVIS")
//调用拦截器intercept方法,传入下一个责任链
val response = interceptor.intercept(next) ?: throw NullPointerException(
"interceptor $interceptor returned null")
if (exchange != null) {
check(index + 1 >= interceptors.size || next.calls == 1) {
"network interceptor $interceptor must call proceed() exactly once"
}
}
check(response.body != null) { "interceptor $interceptor returned a response with no body" }
return response
}