Android-三方源码

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的执行流程

  1. OkhttpClient 实现了Call.Fctory,负责为Request 创建 Call;
  2. RealCall 为Call的具体实现,其enqueue() 异步请求接口、同步的execute()接口通过Dispatcher()调度器进行网络请求,通过 getResponseWithInterceptorChain() 实现;
  3. 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);
    }
  }

RxJava

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流程

  1. Observable.create 创建事件源,但并不生产也不发射事件。
  2. 实现 observer 接口,但此时没有也无法接受到任何发射来的事件。
  3. 订阅 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线程调度

  1. Schedulers.io()等价new IoScheduler() Rxjava 创建了线程池和清理线程 RxCachedWorkerPoolEvictor,定期执行清理任务。
  2. subscribeOn()返回一个 ObservableSubscribeOn 对象,它是 Observable 的一个装饰类, 增加了 scheduler。
  3. 调用 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线程调度

  1. AndroidSchedulers.mainThread()先创建一个包含 handler 的 Scheduler;
  2. observeOn 方法创建 ObservableObserveOn,包含 Scheduler 和 bufferSize 等;
  3. subscribe 被调用后,ObservableObserveOn 的 subscribeActual 方法创建 Scheduler.Worker,调用上游的subscribe()传递自身参数;
  4. 调用 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

是什么?
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) {
    // …… 
}

Butterknife

bind()->createBinding();
传入绑定类activity的class,调用findBindingConstructorForClass()获取绑定构造法bindingconstructor;
使用bindingconstructor.newInstance()进行绑定view的实例化;
具体由AbstractProcessor类process()实现,此方法在编译时自动生成,依据不同注解做处理;
使用binding.brewJava(sdk, debuggable);生成Java文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值