目录
- Retrofit源码分析
- Builder模式创建实例
- Builder()
- baseUrl()
- addConverterFactory
- addCallAdapterFactory()
- build()
- 网络请求接口
- create()
- ServiceMethod
- callAdapter 的使用
- OKHttp
- okhttp的使用方法
- 请求网络
- 异步请求
- Dispatcher调度器
- AsyncCall
- getResponseWithInterceptorChain()
- HTTP缓存
- 责任链的模式
- 同步请求
- RxJava
- Rxjava1.0和Rxjava2.0的区别
- RxJava流程
- Observable
- Observer
- subscribe
- rxjava线程切换
- Observable线程调度
- Schedulers.io()
- subscribeOn
- subscribeActual
- SubscribeTask.class
- scheduleDirect()
- scheduleActual()
- Observer线程调度
- AndroidSchedulers.mainThread()
- observerOn()
- ObserveOnObserver.onNext
- EventBus
- EventBus优势
- EventBus的使用
- EvetntBus3.0 使用
- onEvent 使用
- EventBus 源码解析
- EventBus.getDefault()
- EventBus.getDefault().register()
- 索引获取SubscriberMethod
- 反射获取SubscriberMethod
- EventBus.getDefault.post(Event)
- 注销订阅者
- EventBus.getDefault().postSticky()
- Butterknife
Retrofit源码分析
Builder模式创建实例
retrofit = new Retrofit.Builder()
.baseUrl(GankConfig.HOST)
.addConverterFactory(GsonConverterFactory.create(date_gson))//添加一个转换器,将 gson 数据转换为 bean 类
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加一个适配器,与 RxJava 配合使用
.build();
Builder()
Retrofit.Builder()->Builder()设置平台Platform,依据不同平台设置不同线程池,实现跨平台
baseUrl()
配置服务器地址
addConverterFactory
private final List<Converter.Factory> converterFactories = new ArrayList<>();
public Builder addConverterFactory(Converter.Factory factory){
converterFactories.add(checkNotNull(factory,"factory == null"));
return this;
}
converterFactories在初始化已经添加默认Converter。
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
@Override public Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations,Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
Converter的作用就是将HTTP数据(xml, gson, protobuf)解析成我们想要的java数据。
addCallAdapterFactory()
CallAdapter用一个List维护,用户可以创建多个CallAdapter
private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
Retrofit有默认设置的CallAdapter,是 ExecutorCallAdapterFactory。
callAdapter 其实也是运用了适配器模式,其实质就是网络请求器 Call 的适配器。
CallAdapter 就是用来将 OKHttp 适配给不同的平台的,在 Retrofit 中提供了四种 CallAdapter, 分别如下:
- ExecutorCallAdapterFactory(默认使用)
- GuavaCallAdapterFactory
- Java8CallAdapterFactory
- RxJavaCallAdapterFactory
build()
public Retrofit build() {
//检验 baseUrl
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//创建一个 call,默认情况下使用 okhttp 作为网络请求器
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
//添加一个默认的callAdapter: platform.defaultCallAdapterFactory(platform.defaultCallbackExecutor())
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
网络请求接口
retrofit创建网络请求接口
GankRetrofit gankRetrofit=retrofit.create(GankRetrofit.class);
GankData data= gankRetrofit.getDailyData(2017, 9, 1);
create()
我们主要看 Proxy.newProxyInstance 方法,它接收三个参数:
第一个是一个类加载器,我们所定义的接口的类加载器;
第二个参数是我们定义的接口的 class 对象;
第三个则是一个 InvocationHandler 匿名内部类。
newProxyInstance通过动态代理生成网络接口的代理,我们就可以调用接口文件中定义的方法,这些方法会被动态代理中的invoke()拦截处理。
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//重点看这里
return (T) Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {
service
},
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
invoke()
它接收三个参数,第一个是动态代理,第二个是我们要调用的方法, 第三个是一个参数列表。
接收到参数后,调用loadServiceMethod方法产生ServiceMethod。
create()返回值
由源码可知create()返回值是< T > T,不受约束控制的泛型,可以由调用者自定义的一个类,即是我们自定义网络请求接口。
网络请求结果处理
在调用这个接口类xxxInterface.request(path,apiPath,requestMap).enqueue(new Callback< ResponseBody > callback{…});在callback对象中重写onResponse(),onFailure()方法可对网络请求结果进行处理。
ServiceMethod
loadServiceMethod()
它调用了 ServiceMethod 类,而 ServiceMethod 也使用了 Builder 模式。
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
Builder()
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
//获取接口中的方法名
this.method = method;
//获取方法里的注解
this.methodAnnotations = method.getAnnotations();
//获取方法里的参数类型
this.parameterTypes = method.getGenericParameterTypes();
//获取接口方法里的注解内容
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
build()
1、首先对注解的合法性进行检验,例如,HTTP 的请求方法是 GET 还是 POST,如果不是就会抛出异常;
2、根据方法的返回值类型和注解从 Retrofit 对象的的 callAdapter 列表和 Converter 列表中分别获取到该方法对应的 callAdapter 和 Converter;
3、将传递进来的参数与注解封装在 parameterHandlers 中,为后面的网络请求做准备。
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'" + Utils.getRawType(responseType).getName()
+ "' is not a valid response body type."+
" Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is "+
"required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError( "Multipart can only be specified"+
"on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified"+
"on HTTP methods with request body (e.g., @POST).");
}
}
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not"+
"include a type variable or wildcard: %s", parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
callAdapter 的使用
create 方法的最后一行是这样的: return serviceMethod.callAdapter.adapt(okHttpCall);
最后是调用了 callAdapter 的 adapt 方法,上面我们讲到 Retrofit 在决定使用什么 callAdapter 的 时候是看我们在 addCallAdapterFactory 方法的返回值的。
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable == isAsync ?
new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
}
else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}if (isSingle) {
return observable.singleOrError();
}if (isMaybe) {
return observable.singleElement();
}if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
首先在 adapt 方法中会先判断是同步请求还是异步请求,这里我们以同步请求为例,直接看 CallExecuteObservable。
subscribeActual 方法中去调用了 OKHttpCall 的 execute 方法开始进行网络请求,网络请求完毕之后,会通过 RxJava 的操作符对返回来的数据进行转换,并进行线程的切换
final class CallExecuteObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
CallExecuteObservable(Call<T> originalCall) {
this.originalCall = originalCall;
}
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
observer.onSubscribe(new CallDisposable(call));
boolean terminated = false;
try {
//重点看这里
Response<T> response = call.execute();
if (!call.isCanceled()) {
observer.onNext(response);
}if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
if (terminated) {
RxJavaPlugins.onError(t);
}
else if (!call.isCanceled()) {
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
}
OKHttp
OkHttp的执行流程
- OkhttpClient 实现了Call.Fctory,负责为Request 创建 Call;
- RealCall 为Call的具体实现,其enqueue() 异步请求接口、同步的execute()接口通过Dispatcher()调度器进行网络请求,通过 getResponseWithInterceptorChain() 实现;
- getResponseWithInterceptorChain() 中利用 Interceptor 链条,责任链模式分层实现缓存、透明压缩、网络 IO 等功能;最终将响应数据返回给用户。
okhttp的使用方法
OkHttpClient client = new OkHttpClient();
public OkHttpClient() {
this(new Builder());
}
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
eventListenerFactory = EventListener.factory(EventListener.NONE);
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
pingInterval = 0;
}
OkHttpClient 的属性
final Dispatcher dispatcher;//调度器
final @Nullable
Proxy proxy;//代理
final List<Protocol> protocols;//协议
final List<ConnectionSpec> connectionSpecs;//传输层版本和连接协议
final List<Interceptor> interceptors;//拦截器
final List<Interceptor> networkInterceptors;//网络拦截器
final EventListener.Factory eventListenerFactory;
final ProxySelector proxySelector;//代理选择器
final CookieJar cookieJar;//cookie
final @Nullable
Cache cache;//cache 缓存
final @Nullable
InternalCache internalCache;//内部缓存
final SocketFactory socketFactory;//socket 工厂
final @Nullable
SSLSocketFactory sslSocketFactory;//安全套层socket工厂 用于https
final @Nullable
CertificateChainCleaner certificateChainCleaner;//验证确认响应书,适用HTTPS 请求连接的主机名
final HostnameVerifier hostnameVerifier;//主机名字确认
final CertificatePinner certificatePinner;//证书链
final Authenticator proxyAuthenticator;//代理身份验证
final Authenticator authenticator;//本地省份验证
final ConnectionPool connectionPool;//链接池 复用连接
final Dns dns; //域名
final boolean followSslRedirects;//安全套接层重定向
final boolean followRedirects;//本地重定向
final boolean retryOnConnectionFailure;//重试连接失败
final int connectTimeout;//连接超时
final int readTimeout;//读取超时
final int writeTimeout;//写入超时
请求网络
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
从源码中可以看出 okhttp 实现了Call.Factory接口
interface Factory {
Call newCall(Request request);
}
okhttpClient 如何实现的Call接口
@Override
public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
RealCall 主要方法:同步请求 :client.newCall(request).execute(); 和 异步请求: client.newCall(request).enqueue();
异步请求
RealCall.enqueue() 的实现
RealCall.enqueue()->executorService().execute()->new AsyncCall,创建线程池,将请求入执行队列,依次执行。
RealCall.java
@Override public void enqueue(Callback responseCallback) {
//TODO 不能重复执行
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
//TODO 交给 dispatcher调度器 进行调度
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
synchronized (this) 确保每个call只能被执行一次不能重复执行
利用dispatcher调度器,来进行实际的执行client.dispatcher().enqueue(new AsyncCall(responseCallback));,在上面的OkHttpClient.Builder可以看出 已经初始化了Dispatcher。
Dispatcher调度器
Dispatcher将call 加入到队列中,然后通过线程池来执行call。
//TODO 执行异步请求
synchronized void enqueue(AsyncCall call) {
//TODO 同时请求不能超过并发数(64,可配置调度器调整)
//TODO okhttp会使用共享主机即 地址相同的会共享socket
//TODO 同一个host最多允许5条线程通知执行请求
if (runningAsyncCalls.size() < maxRequests &&
runningCallsForHost(call) < maxRequestsPerHost) {
//TODO 加入运行队列 并交给线程池执行
runningAsyncCalls.add(call);
//TODO AsyncCall 是一个runnable,放到线程池中去执行,查看其execute实现
executorService().execute(call);
} else {
//TODO 加入等候队列
readyAsyncCalls.add(call);
}
}
executorService() 这个方法很简单,只是创建了一个线程池
public synchronized ExecutorService executorService() {
if (executorService == null) {
//TODO 线程池的相关概念 需要理解
//TODO 核心线程 最大线程 非核心线程闲置60秒回收 任务队列
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher",
false));
}
return executorService;
}
AsyncCall
AsyncCall其实就是一个 Runnable,线程池实际上就是执行了execute()。
真正执行请求的是getResponseWithInterceptorChain(); 然后通过回调将Response返回给用户。
final class AsyncCall extends NamedRunnable {
@Override protected void execute() {
boolean signalledCallback = false;
try {
//TODO 责任链模式
//TODO 拦截器链 执行请求
Response response = getResponseWithInterceptorChain();
//回调结果
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
//TODO 移除队列
client.dispatcher().finished(this);
}
}
}
finally 执行了client.dispatcher().finished(this); 通过调度器移除队列,并且判断是否存在等待队列,如果存在,检查执行队列是否达到最大值,如果没有将等待队列变为执行队列。这样也就确保了等待队列被执行。
private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
int runningCallsCount;
Runnable idleCallback;
synchronized (this) {
//TODO calls 移除队列
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
//TODO 检查是否为异步请求,检查等候的队列 readyAsyncCalls,如果存在等候队列,则将等候队列加入执行队列
if (promoteCalls) promoteCalls();
//TODO 运行队列的数量
runningCallsCount = runningCallsCount();
idleCallback = this.idleCallback;
}
//闲置调用
if (runningCallsCount == 0 && idleCallback != null) {
idleCallback.run();
}
}
private void promoteCalls() {
//TODO 检查 运行队列 与 等待队列
if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
//TODO 将等待队列加入到运行队列中
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall call = i.next();
//TODO 相同host的请求没有达到最大,加入运行队列
if (runningCallsForHost(call) < maxRequestsPerHost) {
i.remove();
runningAsyncCalls.add(call);
executorService().execute(call);
}
if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
}
}
getResponseWithInterceptorChain()
真正的执行网络请求和返回响应结果:getResponseWithInterceptorChain()
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
//TODO 责任链
List<Interceptor> interceptors = new ArrayList<>();
//TODO 在配置okhttpClient 时设置的intercept 由用户自己设置
interceptors.addAll(client.interceptors());
//TODO 负责处理失败后的重试与重定向
interceptors.add(retryAndFollowUpInterceptor);
//TODO 负责把用户构造的请求转换为发送到服务器的请求 、把服务器返回的响应转换为用户友好的响应,处理配置请求头等信息
//TODO 从应用程序代码到网络代码的桥梁。首先,它根据用户请求构建网络请求。然后它继续呼叫网络。最后,它根据网络响应构建用户响应。
interceptors.add(new BridgeInterceptor(client.cookieJar()));
//TODO 处理缓存配置,根据条件(存在响应缓存并被设置为不变的或者响应在有效期内)返回缓存响应
//TODO 设置请求头(If-None-Match、If-Modified-Since等) 服务器可能返回304(未修改)
//TODO 可配置用户自己设置的缓存拦截器
interceptors.add(new CacheInterceptor(client.internalCache()));
//TODO 连接服务器,负责和服务器建立连接,这里才是真正的请求网络
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
//TODO 配置okhttpClient 时设置的networkInterceptors
//TODO 返回观察单个网络请求和响应的不可变拦截器列表。
interceptors.addAll(client.networkInterceptors());
}
//TODO 执行流操作(写出请求体、获得响应数据) 负责向服务器发送请求数据、从服务器读取响应数据
//TODO 进行http请求报文的封装与请求报文的解析
interceptors.add(new CallServerInterceptor(forWebSocket));
//TODO 创建责任链
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
//TODO 执行责任链
return chain.proceed(originalRequest);
}
HTTP缓存
辑 OkHttp 内置封装了一个 Cache 类,它利用 DiskLruCache,用磁盘上的有限大小空间进行缓存,按照 LRU 算法进行缓存淘汰;
我们可以在构造 OkHttpClient 时设置 Cache 对象,在其构造函数中我们可以指定目录和缓存大小;
责任链的模式
责任链模式是什么?
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合。 将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
责任链模式在Interceptor应用
采用责任链的模式来使每个功能分开,每个Interceptor自行完成自己的任务,并且将不属于自己的任务交给下一个,简化了各自的责任和逻辑。
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
//TODO 创建新的拦截链,链中的拦截器集合index+1
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
//TODO 执行当前的拦截器-如果在配置okhttpClient,时没有设置intercept默认是先执行:retryAndFollowUpInterceptor 拦截器
Interceptor interceptor = interceptors.get(index);
//TODO 执行拦截器
Response response = interceptor.intercept(next);
return response;
}
okhttp如何通过责任链来进行传递返回数据?
责任链中每个拦截器都会执行chain.proceed()方法之前的代码,等责任链最后一个拦截器执行完毕后会返回最终的响应数据,而chain.proceed() 方法会得到最终的响应数据,这时就会执行每个拦截器的chain.proceed()方法之后的代码。
同步请求
synchronized (this) 避免重复执行;
client.dispatcher().executed(this); 实际上调度器只是将call 加入到了同步执行队列中;
getResponseWithInterceptorChain()请求网络得到响应数据,返回给用户;
client.dispatcher().finished(this); 执行调度器的完成方法,移除队列。
//TODO 同步执行请求 直接返回一个请求的结果
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
//TODO 调用监听的开始方法
eventListener.callStart(this);
try {
//TODO 交给调度器去执行
client.dispatcher().executed(this);
//TODO 获取请求的返回数据
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
//TODO 执行调度器的完成方法 移除队列
client.dispatcher().finished(this);
}
}
Rxjava1.0和Rxjava2.0的区别
在RxJava2里,引入了Flowable这个类:Observable不包含backpressure处理,而Flowable包含。
对于observable
他会按照0,1,2,3,4…的顺序依次消费,并输出log,而没有消费的数据将会都存在内存中。如果在RxJava1中,内存数据超过128个时将会抛出MissingBackpressureException错误;而在RxJava2中并不会报错,数据会一直放到内存中,直到发生OutOfMemoryError。
对于flowable, 在创建时我们设定了FlowableEmitter.BackpressureMode.DROP,一开始他会输出0,1,2,3….127但之后会忽然跳跃到966,967,968 …。中间的部分数据由于缓存不了,被抛弃掉了。
RxJava流程
- Observable.create 创建事件源,但并不生产也不发射事件。
- 实现 observer 接口,但此时没有也无法接受到任何发射来的事件。
- 订阅 observable.subscribe(observer), 此时会调用具体 Observable 的实现类中的 subscribeActual 方法, 此时会才会真正触发事件源生产事件,事件源生产出来的事件通过 Emitter 的 onNext, onError,onComplete 发射给 observer 对应的方法由下游 observer 消费掉。
rxjava的使用示例
// RxJava的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 创建被观察者(Observable) & 定义需发送的事件
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
// 2. 创建观察者(Observer) & 定义响应事件的行为
// 3. 通过订阅(subscribe)连接观察者和被观察者
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
// 默认最先调用复写的 onSubscribe()
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件"+ value +"作出响应" );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
}
}
Observable
事件生产者
事件的源就是将 ObservableOnSubscribe 作为参数传递给 ObservableCreate 的构造函数。
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
// ObservableOnSubscribe 是个接口, 只包含 subscribe 方法,是事件生产的源头。
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
Observer
上游分发事件在以下几个接口中被消费
void onSubscribe(@NonNull Disposable d);
void onNext(@NonNull T t);
void onError(@NonNull Throwable e);
void onComplete();
subscribe
事件是如何被发射给下游的?
当订阅成功后,数据源 ObservableOnSubscribe 开始生产事件,调用 Emitter 的 onNext,onComplete 向下游发射事件, Emitter 包含了 observer 的引用,又调用了 observer onNext,onComplete,这样下游 observer 就接收到了上游发射的数据。
subscribe(订阅)将observable(被观察者)和observer(观察者)连接起来的方法。
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
observer = RxJavaPlugins.onSubscribe(this, observer); // hook ,默认直接返回 observer
subscribeActual(observer); // 这个才是真正实现订阅的方法。
}
// subscribeActual 是抽象方法,所以需要到实现类中去看具体实现,也就是说实现是在上文中提到的 ObservableCreate 中
protected abstract void subscribeActual(Observer<? super T> observer);
ObservableCreate.java
数据源生产事件的 subscribe 方法只有在 observable.onSubscribe(observer)被执行后才执行的。
换言之,事件流是在订阅后才产生。
而 observable 被创建出来时并不生产事件,同时也不发射事件。
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source; // 事件源,生产事件的接口,由我们自己实现
}
@Override protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer); // 发射器
observer.onSubscribe(parent); //直接回调了观察者的 onSubscribe
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
CreateEmitter
CreateEmitter parent = new CreateEmitter(observer);
CreateEmitter 实现了 ObservableEmitter 接口,同时 ObservableEmitter 接口又继承了 Emitter 接口。
CreateEmitter 还实现了 Disposable 接口,这个 disposable 接口是用来判断是否中断事件发射的。 正是它将上游产生的事件发射到下游的。
Emitter 是事件源与下游的桥梁。
CreateEmitter 主要包括方法:
void onNext(@NonNull T value);
void onError(@NonNull Throwable error);
void onComplete();
public void dispose() ;
public boolean isDisposed();
public void onNext(T t) {
if (!isDisposed()) {
// 判断事件是否需要被丢弃
observer.onNext(t);
// 调用Emitter的onNext,它会直接调用observer 的 onNext
}
}
public void onError(Throwable t) {
if (!isDisposed()) {
try {
observer.onError(t);
// 调用 Emitter 的 onError,它会直接调用 observer 的 onError
} finally {
dispose();
// 当 onError 被触发时,执行 dispose(), 后续 onNext, onError, onComplete 就不会继续发射事件了
}
}
}
@Override18 public void onComplete() {
if (!isDisposed()) {
try{
observer.onComplete();
// 调用 Emitter 的 onComplete,它会直接调用 observer 的 onComplete
} finally {
dispose();
// 当 onComplete 被触发时,也会执行 dispose(), 后续 onNext,onError, onComplete同样不会继续发射事件了
}
}
}
rxjava线程切换
Observable线程调度
- Schedulers.io()等价new IoScheduler() Rxjava 创建了线程池和清理线程 RxCachedWorkerPoolEvictor,定期执行清理任务。
- subscribeOn()返回一个 ObservableSubscribeOn 对象,它是 Observable 的一个装饰类, 增加了 scheduler。
- 调用 subscribe()方法,subscribeActual()被调用,才真正执行了 IoSchduler 中的 createWorker()创建线程并在scheduleActual()运行线程。
Schedulers.io()
先分析下 Schedulers.io()
@NonNull public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO); // hook function
// 等价于 return IO;
}
再看看 IO 是什么, IO 是个 static 变量,初始化的地方是
IO = RxJavaPlugins.initIoScheduler(new IOTask()); // 又是 hook function
// 等价于IO = callRequireNonNull(new IOTask());
// 等价于IO = new IOTask().call();
继续看看 IOTask
static final class IOTask implements Callable<Scheduler> {
@Override3 public Scheduler call() throws Exception {
return IoHolder.DEFAULT;5 // 等价于return new IoScheduler();
}
}
IoScheduler 是个 IO 线程调度器
new IoScheduler()后 Rxjava 会创建 CachedWorkerPool 的线程池, 同时也创建并运行了一个名为 RxCachedWorkerPoolEvictor 的清除线程,主要作用是清除 不再使用的一些线程。
public IoScheduler() {
this(WORKER_THREAD_FACTORY);
}
public IoScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference<CachedWorkerPool>(NONE);
start();
}
@Override12 public void start() {
CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
if (!pool.compareAndSet(NONE, update)) {
update.shutdown();
}
}
CachedWorkerPool(long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) {
this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L;
this.expiringWorkerQueue = new ConcurrentLinkedQueue<ThreadWorker>();
this.allWorkers = new CompositeDisposable();
this.threadFactory = threadFactory;
ScheduledExecutorService evictor = null;
Future<?> task = null;
if (unit != null) {
evictor = Executors.newScheduledThreadPool(1, EVICTOR_THREAD_FACTORY);
task = evictor.scheduleWithFixedDelay(this, this.keepAliveTime, this.keepAliveTime, TimeUnit.NANOSECONDS);
}
evictorService = evictor;
evictorTask = task;
}
subscribeOn
RxJavaPlugins.onAssembly就是个 hook function, 等价于直接 return new ObservableSubscribeOn(this, scheduler);, 现在知道了这里的 scheduler 其实就是 IoScheduler。
可以看到这个 ObservableSubscribeOn 继承自 Observable,并且扩展了一些属性,增加了 scheduler。 这就是典型的装饰模式
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
subscribeActual
我们已经知道了 Observable.subscribe()方法最终都是调用了对应的实现类的 subscribeActual 方法。
SubscribeOnObserver 也是装饰模式的体现, 是对下游 observer 的一个 wrap,只是添加 了 Disposable 的管理。
@Override public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
// 没有任何线程调度,直接调用的,所以下游的 onSubscribe 方法没有切换线程
//本文 demo 中下游就是观察者,所以我们明白了为什么只有 onSubscribe 还运行在 main 线程
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
SubscribeTask.class
// 这个类很简单,就是一个 Runnable,最终运行上游的 subscribe 方法
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override10 public void run() {
source.subscribe(parent);
}
}
scheduleDirect()
@NonNull public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
// IoSchedular 中的 createWorker()
final Worker w = createWorker();
// hook decoratedRun=run;
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
// decoratedRun 的 wrap, 增加了 Dispose 的管理
DisposeTask task = new DisposeTask(decoratedRun,w);
// 线程调度
w.schedule(task, delay, unit);
return task;
}
public Worker createWorker() {
// 工作线程是在此时创建的
return new EventLoopWorker(pool.get());
}
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
if (tasks.isDisposed()) {
// don't schedule, we are unsubscribed
return EmptyDisposable.INSTANCE;
}
// action 中就包含上游 subscribe 的 runnable
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
scheduleActual()
最终的线程调度在scheduleActual()方法中执行
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
// decoratedRun = run, 包含上游 subscribe 方法的 runnable
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
// decoratedRun的 wrap, 增加了 dispose 的管理
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
if (parent != null) {
if (!parent.add(sr)) {
return sr;
}
}
// 最终 decoratedRun 被调度到之前创建或从线程池中取出的线程
// 也就是说在 RxCachedThreadScheduler-x 运行
Future<?> f;
try {
if (delayTime <= 0) {
f = executor.submit((Callable<Object>)sr);
} else {
f = executor.schedule((Callable<Object>)sr, delayTime, unit);
}
sr.setFuture(f);
} catch (RejectedExecutionException ex) {
if (parent != null) {
parent.remove(sr);
}
RxJavaPlugins.onError(ex);
}
return sr;
}
Observer线程调度
- AndroidSchedulers.mainThread()先创建一个包含 handler 的 Scheduler;
- observeOn 方法创建 ObservableObserveOn,包含 Scheduler 和 bufferSize 等;
- subscribe 被调用后,ObservableObserveOn 的 subscribeActual 方法创建 Scheduler.Worker,调用上游的subscribe()传递自身参数;
- 调用 ObserveOnObserver 的 onNext调用 scheduler()将处理事件的方法调度到对应的线程中(本例会调度到 main thread),创建scheduleRunnable执行任务,使用handler切换到主线程。
AndroidSchedulers.mainThread()
AndroidSchedulers.mainThread()想当于 new HandlerScheduler(new Handler(Looper.getMainLooper())),原来是利用 Android 的 Handler 来调度到 main 线程的。
/** A {@link Scheduler} which executes actions on the Android main thread. */
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
new Callable<Scheduler>() {
@Override public Scheduler call() throws Exception {
return MainHolder.DEFAULT;
}
});
public static Scheduler initMainThreadScheduler(Callable<Scheduler> scheduler) {
if (scheduler == null) {
throw new NullPointerException("scheduler == null");
}
Function<Callable<Scheduler>, Scheduler> f = onInitMainThreadHandler;
if (f == null) {
return callRequireNonNull(scheduler);
}
return applyRequireNonNull(f, scheduler);
}
observerOn()
public final Observable<T> observeOn(Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}
Observable 的 subscribe 方法最终都是调用 subscribeActual 方法
@Override protected void subscribeActual(Observer<? super T> observer) {
// scheduler 就是前面提到的 HandlerScheduler,所以进入 else 分支
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
// 创建 HandlerWorker
Scheduler.Worker w = scheduler.createWorker();
// 调用 上游 Observable 的 subscribe,将订阅向上传递
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
ObserveOnObserver.onNext
@Override public void onNext(T t) {
if (done) {
return;
}
// 如果是非异步方式,将上游发射的时间加入到队列
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
void schedule() {
// 保证只有唯一任务在运行
if (getAndIncrement() == 0) {
// 调用的就是 HandlerWorker 的 schedule 方法
worker.schedule(this);
}
}
@Override public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
if (run == null)
throw new NullPointerException("run == null");
if (unit == null)
throw new NullPointerException("unit == null");
if (disposed) {
return Disposables.disposed();
}
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
Message message = Message.obtain(handler, scheduled);
message.obj = this;
// Used as token for batch disposal of this worker's runnables.
handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
// Re-check disposed state for removing in case we were racing a call to dispose().
if (disposed) {
handler.removeCallbacks(scheduled);
return Disposables.disposed();
}
return scheduled;
}
schedule 方法将传入的 run 调度到对应的 handle 所在的线程来执行
@Override public void run() {
// 此例子中代码不会进入这个分支,至于 这个 drainFused 是什么,后面章节再讨论。
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
final Observer<? super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
// 从队列 中 queue 中取出事件
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
q.clear();
a.onError(ex);
worker.dispose();
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
//调用下游 observer 的 onNext 将事件 v 发射出 去
a.onNext(v);
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
是什么?
EventBus 是一个 Android 事件发布/订阅框架,通过解耦发布者和订阅者简化 Android 事件传递,事件传递既可用于 Android 四大组件间通讯,也可以用户异步线程和主线程间通讯等等。
事件响应流程
订阅者首先调用 EventBus 的 register 接口订阅某种类型的事件,当发布者通过 post 接口发布该类型的事件时,EventBus 执行调用者的事件响应函数。
EventBus优势
对比 Java 监听器接口(Listener Interfaces)
使用“监听器(Listeners)”接口,实现了监听器接口的类必须将自身注册到它想要监听的类中去。这就意味着 监听与被监听之间属于强关联关系。这种关系就使得单元测试很难进行开展。
对比本地广播管理器(LocalBroadcastManager)
它的 API 不如 EventBus 那样简洁。
此外, 如果你不注意保持 Intent extras 类型的一致,它还可能引发潜在的运行时/类型检测错误。
而使用 EventBus 所传递的消息则是通过你所定义的 Event 类。由于接收者方法是直接与这些类实例打交道,所以所有的数据均可以进行类型检查,这样任何由于类型不一致所导致的错误都可以在编译时刻被发现。
Event 类可以定义成任何类型,你也通过 EventBus 发送/接收任何类。
EventBus的使用
定义事件
public class MessageWrap {
public final String message;
public static MessageWrap getInstance(String message) {
return new MessageWrap(message);
}
private MessageWrap(String message) {
this.message = message;
}
}
注册/注销事件
@Route(path = BaseConstants.LIBRARY_EVENT_BUS_ACTIVITY1)
public class EventBusActivity1 extends CommonActivity<ActivityEventBus1Binding> {
@Override
protected void doCreateView(Bundle savedInstanceState) {
// 为按钮添加添加单击事件
getBinding().btnReg.setOnClickListener(v -> EventBus.getDefault().register(this));
getBinding().btnNav2.setOnClickListener( v ->
ARouter.getInstance()
.build(BaseConstants.LIBRARY_EVENT_BUS_ACTIVITY2)
.navigation());
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onGetMessage(MessageWrap message) {
getBinding().tvMessage.setText(message.message);
}
}
发布事件
@Route(path = BaseConstants.LIBRARY_EVENT_BUS_ACTIVITY2)
public class EventBusActivity2 extends CommonActivity<ActivityEventBus2Binding> {
@Override
protected void doCreateView(Bundle savedInstanceState) {
getBinding().btnPublish.setOnClickListener(v -> publishContent());
}
private void publishContent() {
String msg = getBinding().etMessage.getText().toString();
EventBus.getDefault().post(MessageWrap.getInstance(msg));
ToastUtils.makeToast("Published : " + msg);
}
}
EvetntBus3.0 使用
注册一般是在 onCreate 和 onStart 里注册,尽量不要在 onResume,可能出现多次注册的情况;
取消注册 要写到 onDestroy 方法里,不要写到 onStop 里,有时会出现异常的哦。
EventBus 3 采用注解的方法来接收事件,四种注解
@Subscrible
@Subscrible(threadMode = ThreadMode.ASYNC)
@Subscribe(threadMode = ThreadMode.BACKGROUND)
@Subscribe(threadMode = ThreadMode.MAIN)
分别对应之前的 onEvent()、 onEventAsync()、onEventBackground()、onEventMainThread()。
onEvent 使用
onEvent
发布事件和接收事件线程在同一个线程。
onEventMainThread
不论事件是在哪个线程中发布出来的,接收事件就会在 UI 线程中运行。
onEventBackground
那么如果事件是在 UI 线程中发布出来的,那么 onEventBackground 就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么 onEventBackground 函数直接在该子线程中执行。
onEventAsync
无论事件在哪个线程发布,都会创建新的子线程在执行 onEventAsync.
EventBus 源码解析
EventBus.getDefault()
使用了双重检验锁(单例模式的一种实现方式)的来保证EventBus实例的唯一性。
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
在无参构造函数内调用了带有EventBusBuilder参数的构造函数,这里使用了Builder模式,将参数的构建过程交给EventBusBuilder。
public EventBus() {
this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder) {
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
logSubscriberExceptions = builder.logSubscriberExceptions;
logNoSubscriberMessages = builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}
- subscriptionsByEventType:以EventType(Event对象的Class类)为key,Subscription(订阅者以及一个订阅方法)数组为value。根据EventType可以查询到相应的订阅者及订阅方法。
- typesBySubscriber:以Subscriber(订阅者,即调用register方法的类)为key,EventType数组为value。根据订阅者可以查询到它订阅的所有事件。
- stickyEvents:以EventType为key,Event为value。用来保存粘性事件。
- mainThreadPoster、backgroundPoster、asyncPoster:EventBus支持四种ThreadMode,POSTING、MAIN、BACKGROUND、ASYNC。POSTING直接在发布事件的线程处理,这三个poster分别用来支持剩下的三种Mode。
- indexCount:索引类数目,索引类指的是EventBus利用注解处理器生成的保存订阅者信息的类。如果lib中也用了EventBus,就可能存在多个索引类。
- subscriberMethodFinder:查找及缓存订阅者信息的类。
- logSubscriberExceptions:当事件处理过程发生异常时是否打印日志,默认为true。
- logNoSubscriberMessages:当事件没有订阅者订阅时是否打印日志,默认为true。
- sendSubscriberExceptionEvent:当事件处理过程发生异常时是否发送SubscriberExceptionEvent,默认为true。当为true时,订阅者可以订阅SubscriberExceptionEvent事件。
- sendNoSubscriberEvent:当事件没有订阅者订阅时是否发送NoSubscriberEvent,默认为true。当为true时,订阅者可以订阅NoSubscriberEvent事件。
- throwSubscriberException:当事件处理过程发生异常时是否抛出EventBusException,默认为false。
- eventInheritance:是否支持事件继承,默认为true。当为true时,post一个事件A时,若A是B的子类或者A实现了接口B,订阅B的订阅者也能接收到事件。
- executorService:线程池,负责线程调度。
EventBus.getDefault().register()
当注册订阅者时,会通过SubscriberMethodFinder的findSubscriberMethods来获取SubscriberMethod数组,SubscriberMethod保存了订阅方法的信息。
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
得到SubscriberMethod数组后,依次进行注册。先看看获取到SubscriberMethod数组后,是如何通过subscribe进行订阅的:
主要是将EventType -> Subscription的映射加入到subscriptionsByEventType,将Subscriber -> EventType的映射与加入到typesBySubscriber中。subscriptionsByEventType里每个事件的Subscription是按照优先级排序的,优先级高的订阅者可以中途通过cancelEventDelivery来拦截。
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);
// 粘性事件处理, 将在第五小节分析
}
findSubscriberMethods是如何获取到SubscriberMethod数组的:
如果ignoreGeneratedIndex是false的话,就采用注解处理器生成索引类去获取SubscriberMethod;否则采用反射的方式。
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);
} else {
subscriberMethods = findUsingInfo(subscriberClass);
}
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass
+ " and its super classes have no public methods with the @Subscribe annotation");
} else {
METHOD_CACHE.put(subscriberClass, subscriberMethods);
return subscriberMethods;
}
}
索引获取SubscriberMethod
会通过prepareFindState获取FindState对象,FindState保存了在查找SubscriberMethod时的一些属性,并封装了检验合法性的方法。
得到FindState后,先通过getSubscriberInfo获取订阅者信息SubscriberInfo:
SubscriberInfoIndex的getSubscriberInfo来获得订阅者信息SubscriberInfo。SubscriberInfoIndex就是采用注解处理器生成的索引类,包含了订阅者及其订阅方法的信息。
private SubscriberInfo getSubscriberInfo(FindState findState) {
if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
if (findState.clazz == superclassInfo.getSubscriberClass()) {
return superclassInfo;
}
}
if (subscriberInfoIndexes != null) {
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
反射获取SubscriberMethod
找到SubscriberMethod后,通过moveToSuperclass一层层向上寻找。最后getMethodsAndRelease重置FindState内的临时变量,并放置到对象池中。
private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) {
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
findUsingReflectionInSingleClass(findState);
findState.moveToSuperclass();
}
return getMethodsAndRelease(findState);
}
在findUsingReflectionInSingleClass,先获取类里面的Method,通过getDeclaredMethods()或者getMethods()。
获取到Method数组后,校验包含@Subscribe注解的方法是不是为Public,是不是不含有abstract、static、bridge、synthtic修饰符,参数是不是只有一个。
通过的话,再调用FindState的checkAdd校验,然后加到FindState的subscriberMethods里。
private void findUsingReflectionInSingleClass(FindState findState) {
// 先获取类里面的所有方法。
Method[] methods;
try {
// This is faster than getMethods, especially when subscribers are fat classes like Activities
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
// Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
// 遍历Method,寻找包含@Subscribe注解的方法,并对合法性进行检测。
for (Method method : methods) {
int modifiers = method.getModifiers();
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
Class<?> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
ThreadMode threadMode = subscribeAnnotation.threadMode();
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException("@Subscribe method " + methodName +
"must have exactly 1 parameter but has " + parameterTypes.length);
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException(methodName +
" is a illegal @Subscribe method: must be public, non-static, and non-abstract");
}
}
}
EventBus.getDefault.post(Event)
EventBus会通过ThreadLocal为每个线程维护一个PostingThreadState对象,里面包含分发队列eventQueue、是否主线程isMainThread、是否分发中isPosting、是否取消canceled、当前正在分发的事件和Subscription。
/** Posts the given event to the event bus. */
public void post(Object event) {
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
if (!postingState.isPosting) {
postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
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;
}
}
}
post方法这里的逻辑比较简单,将事件加到队列中,如果此时未在分发中时,就调用postSingleEvent->postSingleEventForEventType->postToSubscription进行分发。
invokeSubscriber方法内利用Subscription里面的SubscriberMethod,反射调用订阅事件的方法。切换到主线程是用的Handler,而切换到新线程则使用线程池。
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 {
mainThreadPoster.enqueue(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
注销订阅者
调用unsubscribeByEventType逐一取消订阅即可,将subscription和subscriber依次从subscriptionsByEventType,typesBySubscriber这两个map中移除
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 {
Log.w(TAG, "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--;
}
}
}
}
EventBus.getDefault().postSticky()
所谓粘性事件,指的是订阅者在事件发送之后才注册的也能接收到的事件。
到粘性事件其实很简单,只是将事件缓存起来,等到注册订阅者时再做判断。checkPostStickyEventToSubscription方法内调用了postToSubscription
public void postSticky(Object event) {
synchronized (stickyEvents) {
stickyEvents.put(event.getClass(), event);
}
// Should be posted after it is putted, in case the subscriber wants to remove immediately
post(event);
}
// 既然粘性事件是在注册时能接收到之前发送的事件,看看注册时subscribe有关的逻辑:
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
// ……
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 {
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, Looper.getMainLooper() == Looper.myLooper());
}
}
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
// ……
}
bind()->createBinding();
传入绑定类activity的class,调用findBindingConstructorForClass()获取绑定构造法bindingconstructor;
使用bindingconstructor.newInstance()进行绑定view的实例化;
具体由AbstractProcessor类process()实现,此方法在编译时自动生成,依据不同注解做处理;
使用binding.brewJava(sdk, debuggable);生成Java文件。