Retrofit 請求網絡
實際上是使用 Retrofit 接口層封裝請求參數、Header、Url 等信息,之後由 OkHttp完成後續的請求操作,在服務端返回數據之後,OkHttp 將原始的結果交給 Retrofit,後者根據用戶的需求對結果進行解析的過程。Retrofit的大概原理過程如下:
- Retrofit 將 Http請求 抽象 成 Java接口
- 在接口裏用 註解 描述和配置 網絡請求參數
- 用動態代理 的方式,動態將網絡請求接口的註解 解析 成HTTP請求
- 最後執行HTTP請求
先看調用方式:
1、Retrofit之kotlin使用方式
- 1、創建一個api服務管理類
/**
* Api管理工具類,通過該類創建相應的api-service類
*/
object ApiServiceManager {
private val gson = GsonBuilder().registerTypeAdapter(Date::class.java, JsonDeserializer<Date> { json, _, _ -> Date(json.asJsonPrimitive.asLong) }).create()
private val mRetrofit: Retrofit = Retrofit.Builder()
.baseUrl(RequestDomainConfig.getRequestDefault())
.client(HttpClientManager.mOkHttpClient)//OKHTTP網絡請求
.addConverterFactory(GsonConverterFactory.create(gson))//添加json解析器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加RxJava轉換器
.build()
fun <T> create(service: Class<T>): T = mRetrofit.create(service)
}
- 2、創建一個服務接口類,供retrofit解析註解
interface ApiUserService {
//用戶登錄
@POST("userAuth.login")
fun loginByAccount(@Body httpRequest: HttpRequest): Observable<UserInfoVo>
- 3、創建接口調用類(真正調用接口)
object ApiUser {
private val sService = ApiServiceManager.create(ApiUserService::class.java)
/**
* 用戶登錄
*/
fun <E> loginByAccount(rxObserver: RxObserver<UserInfoVo>, mView: LifecycleProvider<E>, account: String, password: String) {
sService.loginByAccount(HttpRequest.obtainHttpRequest(HttpEntry("account",account),
HttpEntry("pwd", password)))//請求參數
.compose(RxHelper.handleSingleResult())//封裝RXJava返回值的解析
.bindToLifecycle(mView)//綁定生命週期
.subscribe(rxObserver)
}
}
2、retrofit類源碼分析
先看構造函數和成員變量
public final class Retrofit {
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
final okhttp3.Call.Factory callFactory;// 生產網絡請求器(Call)的工廠,默認使用OkHttp
final HttpUrl baseUrl;// url地址
final List<Converter.Factory> converterFactories;// 數據轉換器(converter)工廠
final List<CallAdapter.Factory> callAdapterFactories;// 生產網絡請求適配器(CallAdapter)的工廠List
final @Nullable Executor callbackExecutor;// 回調方法執行器
final boolean validateEagerly; // 是否提前對業務接口中的註解進行驗證轉換的標誌位
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
Retrofit.Builder 靜態內部類
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private @Nullable HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get()); // Retrofit支持Android Java8 默認Platform 三種平臺,此處確認當前是在哪個平臺環境運行
}
Builder(Retrofit retrofit) {
platform = Platform.get();
callFactory = retrofit.callFactory;
baseUrl = retrofit.baseUrl;
****省略代碼
}
}
retrofit是通過builder()方法來創建的,再看builder()方法:
public Retrofit build() {
//請求地址不可空
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//默認爲OKHTTP
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
***省略代碼
}
最後看create方法:關於動態代理的使用可以看看這篇文章https://blog.csdn.net/yaomingyang/article/details/80981004
public <T> T create(final Class<T> service) {
//校驗是否爲接口,且不能繼承其他接口
Utils.validateServiceInterface(service);
// 是否需要提前解析接口方法
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//動態代理,返回一個 service 接口的代理對象
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable 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);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
3、Platform類解析,用來支持java8版本之下的java平臺。
class Platform {
...
// 無回調執行器,在哪裏創建的,就在哪裏回調
Executor defaultCallbackExecutor() {
return null;
}
// 平臺默認的回調適配器工廠列表爲new DefaultCallAdapterFactory(callbackExecutor)
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
return singletonList(new DefaultCallAdapterFactory(callbackExecutor));
}
// 默認回調適配器工廠數量爲1
int defaultCallAdapterFactoriesSize() {
return 1;
}
// 默認的轉換器工廠列表爲空列表
List<? extends Converter.Factory> defaultConverterFactories() {
return emptyList();
}
// 是否是默認方法
boolean isDefaultMethod(Method method) {
return false;
}
// 調用指定類默認的方法會拋異常,即不支持調用非默認方法
@Nullable Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
throw new UnsupportedOperationException();
}
...
}
- isDefaultMethod()返回false,表示傳入的Method都告知不是默認方法(默認方法是一種公共的非抽象實例方法,即帶有主體的非靜態方法,在接口中聲明)
- invokeDefaultMethod返回異常,表示調用非默認方法不支持
android
static class Android extends Platform {
// 平臺默認的回調執行器 回調線程是UI線程
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
// 是否是默認方法
@Override boolean isDefaultMethod(Method method) {
// 如果安卓構建版本小於24(安卓7.0),則直接返回是非默認方法,否則正常返回method.isDefault()
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
//回調執行器必須不爲空,回調適配器工廠列表版本小於Android7返回new DefaultCallAdapterFactory(callbackExecutor)單獨組成的不可變list,否則返回CompletableFutureCallAdapterFactory.INSTANCE和DefaultCallAdapterFactory(callbackExecutor)組成的不可變list
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
// CompletableFutureCallAdapterFactory是支持CompletableFutureCall,是java8特性
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
// 默認的回調適配器工程個數,和defaultCallAdapterFactories對應
@Override int defaultCallAdapterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
}
// 默認的轉換器工廠
@Override List<? extends Converter.Factory> defaultConverterFactories() {
// 如果平臺支持java8,則讓Converter支持java8操作符
return Build.VERSION.SDK_INT >= 24
? singletonList(OptionalConverterFactory.INSTANCE)
: Collections.<Converter.Factory>emptyList();
}
// 默認轉換器工廠個數
@Override int defaultConverterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
}
//安卓平臺的主線程執行器
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
- Android有默認的MainThreadExecutor,就是Android主線程任務執行器,默認的CallAdapter.Factory任務回調適配器工廠。
- 從這裏就可以看出Android平臺上,Retrofit執行任務默認是在主線程。
Java8
static class Java8 extends Platform {
// 默認method.isDefault()
@Override boolean isDefaultMethod(Method method) {
return method.isDefault();
}
// 支持調用默認方法
@Override Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
// Because the service interface might not be public, we need to use a MethodHandle lookup
// that ignores the visibility of the declaringClass.
//Java反射機制的構造器
Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true);
return constructor.newInstance(declaringClass, -1 /* trusted */)
.unreflectSpecial(method, declaringClass)
.bindTo(object)
.invokeWithArguments(args);
}
// 默認適配器工廠列表,和Android差不多
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
List<CallAdapter.Factory> factories = new ArrayList<>(2);
factories.add(CompletableFutureCallAdapterFactory.INSTANCE);
factories.add(new DefaultCallAdapterFactory(callbackExecutor));
return unmodifiableList(factories);
}
// 默認適配器工廠個數
@Override int defaultCallAdapterFactoriesSize() {
return 2;
}
// 默認轉換器工廠列表
@Override List<? extends Converter.Factory> defaultConverterFactories() {
return singletonList(OptionalConverterFactory.INSTANCE);
}
// 默認轉換器工廠個數
@Override int defaultConverterFactoriesSize() {
return 1;
}
}
- isDefaultMethod():返回method.isDefault()
- invokeDefaultMethod():調用非默認方法接口。
- 關於構造器使用可以看看這篇文章 https://www.jianshu.com/p/49448c942d39