简单使用
1.github官网:https://square.github.io/retrofit/
2.介绍:
- App应用程序通过Retorfit请求网络,实际上是使用Retrofit接口封装请求参数,之后由OKHttp完成后续的请求操作
- 在服务端返回数据之后,OKHttp将原始的结果交给Retrofit,retrofit根据用户的需求对结果进行解析
3.添加依赖和添加网络请求权限:
compile ‘com.squareup.retrofit2:retrofit:2.3.0’
compile ‘com.squareup.retrofit2:converter-gson:2.3.0’
compile ‘com.squareup.retrofit2:converter-scalars:2.3.0’
compile ‘com.squareup.retrofit2:adapter-rxjava:2.3.0’
4.使用
- 封装参数
public class MyResponse {
String name;
int age;
String color;
String address;
}
- 请求参数接口
public interface MyInterface {
//拼接参数baseUrl+users/{user}/repos=https://api.github.com/?users=repos
@GET("users/{user}/repos")
Call<List<MyResponse>> getCall();
}
- retrofit简单使用
public void MyRetrofit() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())//设置数据解析器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//支持Rxjava
.build();
MyInterface myInterface=retrofit.create(MyInterface.class);
Call<List<MyResponse>> call = myInterface.getCall();
call.enqueue(new Callback<List<MyResponse>>() {
@Override
public void onResponse(Call<List<MyResponse>> call, Response<List<MyResponse>> response) {
System.out.println(response.body());
}
@Override
public void onFailure(Call<List<MyResponse>> call, Throwable t) {
System.out.println("请求失败");
}
});
}
5.代理
- 静态代理
//抽象接口
public abstract class AbstroctObect {
public abstract void operation();
}
//真实对象
public class RealObject extends AbstroctObect {
@Override
public void operation() {
System.out.println("真实对象");
}
}
//代理对象
public class ProxyObject extends AbstroctObect {
//持有真实对象
RealObject realObject;
public ProxyObject(RealObject realObject) {
this.realObject = realObject;
}
@Override
public void operation() {
System.out.println("真实对象调用方法之前做一些事情");
if(realObject==null){
realObject=new RealObject();
}
realObject.operation();
System.out.println("真实对象调用方法之后做一些事情");
}
}
- 动态代理
//subject表示代理对象和非代理对象都需要执行的方法,相当于静态代理中的抽象方法
public interface Subject {
void shopping();
}
//真实对象
public class Man implements Subject {
@Override
public void shopping() {
System.out.println("我要买可口可乐");
}
}
//动态代理生成
public class Proxy implements InvocationHandler{
private Object target;//要代理的真实对象
public Proxy(Object object){
this.target=object;
}
//args某个方法的所有参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("proxy:"+proxy.getClass().getSimpleName());
System.out.println("before:");
method.invoke(target,args);
System.out.println("after:");
return null;
}
}
//使用
public static void main(String[]args){
Subject man=new Man();
Proxy proxy=new Proxy(man);
//真实的代理对象
Subject subject = (Subject) java.lang.reflect.Proxy.newProxyInstance(man.getClass().getClassLoader()
, man.getClass().getInterfaces(), proxy);
subject.shopping();
//获得真实对象的代理对象所对应的class对象的名称,用字符串表示
System.out.println(subject.getClass().getName());
}
6.retrofit网络通信八步
- 1.创建retrofit实例
- 2.定义一个网络请求接口中的方法添加注解
- 3.通过动态代理生成网络请求对象
- 4.通过网络请求适配器将网络请求对象进行平台适配(android ,java,IOS)
- 5.通过网络请求执行器 发起网络请求
- 6.通过数据转换器 解析数据
- 7.通过回调执行器,切换主线程
- 8.用户在主线程处理结果
7.retrofit七个关键成员变量
//缓存 ServiceMethod:网络请求接口添加注解解析后的对象
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
//请求网络请求OKhTTP对象的工厂
final okhttp3.Call.Factory callFactory;
final HttpUrl baseUrl;
//数据转换器对象工厂
final List<Converter.Factory> converterFactories;
//网络适配器工厂
final List<CallAdapter.Factory> adapterFactories;
//用于执行回调,默认主线程
final @Nullable Executor callbackExecutor;
//判断是否需要立即解析集合中的数据
final boolean validateEagerly;
源码分析
1. Retrofit.Builder()源码解析
public Builder() {
//看下Platform.get方法,如何获得判断不同平台
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
//添加一个转换器工厂,可以自己添加(如GsonConverterFactory),默认是BuiltInConverters工厂
converterFactories.add(new BuiltInConverters());
}
1.1Platform.get
//看下findPlatform
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
1.2findPlatform:我们只需要关心android即可
Class.forName("android.os.Build");//通过反射获得
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
static class Android extends Platform {
//默认是主线程回调
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
//默认适配器工厂
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
//这就是为什么可以实现主线程切换
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
2.baseUrl,addConverterFactory,addCallAdapterFactory源码分析
2.1.baseUrl
public Builder baseUrl(String baseUrl) {
//检查baseurl不为空
checkNotNull(baseUrl, "baseUrl == null");
//将string类型的url转换成HttpUrl
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
2.2addConverterFactory源码分析
public Builder addConverterFactory(Converter.Factory factory) {
//添加到集合中
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
看下我们调用的时候 .addConverterFactory(GsonConverterFactory.create())中如何创建Gson
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
2.3addCallAdapterFactory源码分析
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
3.Retrofit中build源码分析
public Retrofit build() {
//url不能为空
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//获得okhttpclient
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);
//默认平台
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// 数据解析工厂
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
4. MyInterface myInterface=retrofit.create(MyInterface.class);源码解析
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, @Nullable Object[] args)
throws Throwable {
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);
}
});
}
4.1eagerlyValidateMethods源码分析
private void eagerlyValidateMethods(Class<?> service) {
//获得平台
Platform platform = Platform.get();
//获得所有的方法
for (Method method : service.getDeclaredMethods()) {
//platform.isDefaultMethod(method)返回为false
if (!platform.isDefaultMethod(method)) {
//看下这个,最终获得ServiceMethod<?, ?>对象
loadServiceMethod(method);
}
}
}
4.2 loadServiceMethod
ServiceMethod<?, ?> loadServiceMethod(Method method) {
// 获取Map<Method, ServiceMethod<?, ?>>中ServiceMethod<?, ?>
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
//如果不为空直接返回
if (result != null) return result;
//保证线程安全
synchronized (serviceMethodCache) {
//method相当于key,获得value值
result = serviceMethodCache.get(method);
if (result == null) {
//看下这个源码
result = new ServiceMethod.Builder<>(this, method).build();
//如果为空,添加进去
serviceMethodCache.put(method, result);
}
}
return result;
}
4.3 ServiceMethod.Builder<>(this, method).build()
//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根据返回值的类型和参数
public ServiceMethod build() {
//下面两个方法类似
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
//根据获得的所有注解的方法,进行相应的操作,如get,post
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
//获得注解参数的长度
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);
}
return new ServiceMethod<>(this);
}
5.同步请求
Response<T> execute() throws IOException;
//调用的是OKHttpCall中的execute方法
@Override public Response<T> execute() throws IOException {
//实际创建的是OKhttp3的call对象
okhttp3.Call call;
synchronized (this) {
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
//取消call
if (canceled) {
call.cancel();
}
//调用了okhttp的execute方法
return parseResponse(call.execute());
}
//createRawCall源码
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
//serviceMethod.toRequest(args)源码
Request toRequest(@Nullable Object... args) throws IOException {
//创建requestBuilder对象
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args != null ? args.length : 0;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
//返回request
return requestBuilder.build();
}
6.异步请求:总体和同步类似
void enqueue(Callback<T> callback);
//OKHttpClient中的enqueue的方法
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
//实际创建的是okhttp3汇中的call
okhttp3.Call call;
synchronized (this) {
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
//和同步请求方法一样,所以不阐述
call = rawCall = createRawCall();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
//最终实际调用的是OkHttp中的方法
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});