商城网站制作多少钱,异地备案 网站,ui设计培训哪家好,莱芜高新区目录
一#xff0c;Retrofit的基本使用
1.定义api接口
2.创建Retrofit实例
3.获取api接口实例发起请求
二#xff0c;静态代理和动态代理
1#xff0c;静态代理
2#xff0c;动态代理
三#xff0c;动态代理获取Api接口实例
四#xff0c;解析接口方法注解…目录
一Retrofit的基本使用
1.定义api接口
2.创建Retrofit实例
3.获取api接口实例发起请求
二静态代理和动态代理
1静态代理
2动态代理
三动态代理获取Api接口实例
四解析接口方法注解生成请求方法
五代理发起网络请求
六Retrofit如何实现线程切换 一Retrofit的基本使用
1.定义api接口
public interface ApiService {// GET 请求示例GET(users/{id})CallUser getUser(Path(id) int userId);// POST 请求示例POST(users)CallUser createUser(Body User user);// 带查询参数的 GET 请求示例GET(users)CallListUser getUsers(Query(page) int page, Query(size) int size);
}2.创建Retrofit实例
public class ApiClient {private static final String BASE_URL https://api.github.com/;private static Retrofit retrofit;public static Retrofit getClient() {if (retrofit null) {retrofit new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 解析器.build();}return retrofit;}
}3.获取api接口实例发起请求
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;public class MainActivity extends AppCompatActivity {Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取 apiService 实例ApiService apiService ApiClient.getClient().create(ApiService.class);// 创建请求CallUser call apiService.getUser(octocat);// 异步请求call.enqueue(new CallbackUser() {Overridepublic void onResponse(CallUser call, ResponseUser response) {if (response.isSuccessful()) {// 请求成功处理数据User user response.body();Log.d(Retrofit, User: user.getName());} else {// 请求失败Log.e(Retrofit, Request failed);}}Overridepublic void onFailure(CallUser call, Throwable t) {// 请求失败Log.e(Retrofit, Request error, t);}});}
}从Retrofit的使用入手Retrofit的核心在于
通过动态代理获取apiService实例对api请求方法进行拓展。在代理对象的invoke方法中对接口方法进行解析解析注解参数参数注解返回类型等。代理用于发送请求的Call对象执行网络请求并拦截响应。底层使用Handler机制切换到主线程并将响应结果返回。 二静态代理和动态代理
首先我们先了解一下代理模式 代理模式通过代理对象来代替真实对象的访问从而在不修改原对象的情况下对原对象的方法进行拓展 代理模式一般包含这几个元素 委托类被代理的类接口委托类实现的方法代理类 1静态代理
静态代理分为以下几个步骤
创建一个接口定义方法创建一个委托类实现接口创建一个代理类持有委托类的引用实现与委托类相同的接口
1创建接口
/*
委托接口*/
interface ClientInterface {fun call()
}
2创建委托类实现接口
/*
委托类*/
class Client : ClientInterface {override fun call() {println(Client Call)}
}
3创建代理类实现与委托类相同的接口
/*
代理类*/
class Proxy : ClientInterface {var client : Client? nullfun setInstance(client: Client){this.client client;}override fun call() {println(proxy pre call)client?.call()println(proxy aft call)}
}
这样我们就可以通过使用代理类的call方法从而对委托类的方法进行拓展
2动态代理
动态代理与静态代理的区别就是动态代理的代理对象由Java中的Proxy.newProxyInstance在运行时动态生成。
CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class?[] interfaces,InvocationHandler h)throws IllegalArgumentException
这个方法需要的三个参数为 loader委托类的类加载器interfaces委托类实现的接口h一个实现了InvocationHandler的类在这个类的invoke方法中对委托类的方法进行拓展
1同样创建委托类和接口
/*
委托类也就是代理对象
*/
class Client : ClientInterface {override fun call() {println(client call)}
}/*
委托接口代理类实现的接口*/
interface ClientInterface {fun call()fun call1()
}
2创建实现InvocationHandler的类
/*
实现了InvocationHandler的类*/
class CallInvocationHandler(private var target: Any) : InvocationHandler {//代理类调用的方法会被转发到这里运行override fun invoke(proxy: Any, method: Method, args: Arrayout Any?): Any? {println(before client: ${args.toString()} call: ${method.name})return method.invoke(target, args)}
}
3使用Proxy.newProxyInstance()生成代理对象
class Application3 {fun main(){val client : ClientInterface Client()val proxy Proxy.newProxyInstance(client::class.java.classLoader, //代理对象的类加载器用于加载代理对象arrayOf(client::class.java), //代理对象实现的接口也就是代理对象要进行的业务CallInvocationHandler(client) //实现了 InvocationHandler 接口的对象通过代理类调用代理对象的方法时就会转发到invoke方法中被调用) as Clientproxy.call();}
}
动态代理JDK动态代理只能代理实现了接口的类所以与其说代理类代理了委托类不如说它是代理了接口
三动态代理获取Api接口实例
当我们明白了动态代理之后我们再来看Retrofit的create方法
private val apiService : ApiService RetrofitClient.getInstance().create(ApiService::class.java)public T T create(final ClassT service) {validateServiceInterface(service);//动态代理获取ApiService的代理对象return (T)Proxy.newProxyInstance(service.getClassLoader(),new Class?[] {service},new InvocationHandler() {private final Platform platform Platform.get();private final Object[] emptyArgs new Object[0];Overridepublic Nullable Object invoke(Object proxy, Method method, Nullable Object[] args)throws Throwable {// object类中的方法直接调用if (method.getDeclaringClass() Object.class) {return method.invoke(this, args);}args args ! null ? args : emptyArgs;//检查是否含有默认实现如果有直接按默认实现调用//没有则进入loadServiceMethod方法return platform.isDefaultMethod(method)? platform.invokeDefaultMethod(method, service, proxy, args): loadServiceMethod(method).invoke(args);}});
}//在这里对接口中的方法进行解析
ServiceMethod? loadServiceMethod(Method method) {//请求方法缓存避免重复加载ServiceMethod? result serviceMethodCache.get(method);if (result ! null) return result;synchronized (serviceMethodCache) {result serviceMethodCache.get(method);if (result null) {//没有缓存解析方法result ServiceMethod.parseAnnotations(this, method);serviceMethodCache.put(method, result);}}return result;
}
可见Retrofit通过create方法创建了一个ApiService的代理类。通过ApiService代理类调用请求方法时就会被转发到InvocationHandler的invoke方法中进行解析loadServiceMethod和调用invoke。
四解析接口方法注解生成请求方法
接着Retrofit通过ServiceMethod类对方法及方法注解进行解析
abstract class ServiceMethodT {static T ServiceMethodT parseAnnotations(Retrofit retrofit, Method method) {//构建请求工厂RequestFactory requestFactory RequestFactory.parseAnnotations(retrofit, method);...//封装形成完整的可执行的请求return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);}abstract Nullable T invoke(Object[] args);
}
ServiceMethod是一个抽象类实现类为HttpServiceMethod。
ServiceMethod首先构建了一个RequestFactoryRequestFactory中封装了从接口方法解析到的信息包括
请求方法GET POST等baseUrl和请求的相对路径请求头请求参数请求体等 final class RequestFactory {static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {return new Builder(retrofit, method).build();}private final Method method; //接口方法private final HttpUrl baseUrl; //baseUrlfinal String httpMethod; //请求方法 getpost等private final Nullable String relativeUrl; //请求的相对路径private final Nullable Headers headers; //请求头private final Nullable MediaType contentType; //请求体MIME类型private final boolean hasBody; //是否包含请求体private final boolean isFormEncoded; //是否是表单编码请求private final boolean isMultipart; //是否是多部分请求private final ParameterHandler?[] parameterHandlers; //参数处理数组根据参数注解决定如何处理参数final boolean isKotlinSuspendFunction; //是否为kotlin挂起函数}接着在HttpServiceMethod中使用适配器格式转换器结合RequestFactory将请求信息封装为可执行的完整的请求
核心代码
static T HttpServiceMethodT parseAnnotations(Retrofit retrofit, Method method, RequestFactory requestFactory) {CallAdapterT, ? callAdapter createCallAdapter(retrofit, method);Type responseType callAdapter.responseType();ConverterResponseBody, T responseConverter createResponseConverter(retrofit, method, responseType);return new HttpServiceMethod(requestFactory, callAdapter, responseConverter);
}核心组件 callAdapter适配器将底层的call对象适配为用户接口返回的类型CallT, FlowT, LiveDataT等 converter格式转化器例如转化Json格式数据 RequestFactory之前封装好的请求信息
五代理发起网络请求
在请求构建完毕后就会调用invoke方法具体调用的是HttpServiceMethod类中的invoke方法
invoke方法中又返回了adapt方法的调用adapt方法的具体实现交给三个子类 CallAdaptedResponseT, ReturnT适配返回类型为标准Java类型如CallT或者RxJava的SingleT, ObserverT类型。 SuspendForResponseResponseT适配 Kotlin 协程场景当接口方法的返回类型为 suspend fun 且需要返回一个 RespondT完整的 HTTP 响应对象时使用。 SuspendForBodyResponseT适配 Kotlin 协程场景当接口方法的返回类型为 suspend fun 且只需要返回响应体对象 T不需要完整的 HTTP 响应对象时使用。 Overridefinal Nullable ReturnT invoke(Object[] args) {CallResponseT call new OkHttpCall(requestFactory, args, callFactory, responseConverter);return adapt(call, args);}protected abstract Nullable ReturnT adapt(CallResponseT call, Object[] args);static final class CallAdaptedResponseT, ReturnT extends HttpServiceMethodResponseT, ReturnT {}static final class SuspendForResponseResponseT extends HttpServiceMethodResponseT, Object {}static final class SuspendForBodyResponseT extends HttpServiceMethodResponseT, Object {}
一般情况使用的都是CallAdapted子类CallAdapted子类中的adapt方法返回callAdapter的adapt方法调用
static final class CallAdaptedResponseT, ReturnT extends HttpServiceMethodResponseT, ReturnT {private final CallAdapterResponseT, ReturnT callAdapter;CallAdapted(RequestFactory requestFactory,okhttp3.Call.Factory callFactory,ConverterResponseBody, ResponseT responseConverter,CallAdapterResponseT, ReturnT callAdapter) {super(requestFactory, callFactory, responseConverter);this.callAdapter callAdapter;}Overrideprotected ReturnT adapt(CallResponseT call, Object[] args) {return callAdapter.adapt(call);}}
返回类型为CallT对应的callAdapter由Retrofit默认添加的DefaultCallAdapterFactory生成
Overridepublic Nullable CallAdapter?, ? get(Type returnType, Annotation[] annotations, Retrofit retrofit) {if (getRawType(returnType) ! Call.class) {return null;}if (!(returnType instanceof ParameterizedType)) {throw new IllegalArgumentException(Call return type must be parameterized as CallFoo or Call? extends Foo);}final Type responseType Utils.getParameterUpperBound(0, (ParameterizedType) returnType);final Executor executor Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)? null: callbackExecutor;return new CallAdapterObject, Call?() {Overridepublic Type responseType() {return responseType;}Overridepublic CallObject adapt(CallObject call) {//这里使用代理模式将okHttpCall的功能代理到ExecutorCallbackCall中return executor null ? call : new ExecutorCallbackCall(executor, call);}};}
adapt方法最后返回ExecutorCallbackCall对象所以调用ApiService代理类的请求方法最终返回的是call对象为ExecutorCallbackCall对象。
或者说是使用了代理模式将call的功能代理到了ExecutorCallbackCall中当我们调用call的异步方法enquque时最终调用到的是ExecutorCallbackCall的enquque方法。
在ExecutorCallbackCall的enquque方法调用了原call对象的异步请求方法并拦截了onResponse 和 onFailure 回调切换到指定的线程通常是主线程也就是Retrofit中的onResponse 和 onFailure 回调最终是在主线程中获取到的。
至此Retrofit的整个流程就结束了。
static final class ExecutorCallbackCallT implements CallT {final Executor callbackExecutor;final CallT delegate; //被代理的call对象ExecutorCallbackCall(Executor callbackExecutor, CallT delegate) {this.callbackExecutor callbackExecutor;this.delegate delegate;}Overridepublic void enqueue(final CallbackT callback) {Objects.requireNonNull(callback, callback null);//调用原call对象的异步请求方法delegate.enqueue(new CallbackT() {//拦截底层的 onResponse 和 onFailure 回调切换到指定的线程通常是主线程。Overridepublic void onResponse(CallT call, final ResponseT response) {//这里切换到主线程callbackExecutor.execute(() - {if (delegate.isCanceled()) {callback.onFailure(ExecutorCallbackCall.this, new IOException(Canceled));} else {callback.onResponse(ExecutorCallbackCall.this, response);}});}Overridepublic void onFailure(CallT call, final Throwable t) {callbackExecutor.execute(() - callback.onFailure(ExecutorCallbackCall.this, t));}});}Overridepublic boolean isExecuted() {return delegate.isExecuted();}Overridepublic ResponseT execute() throws IOException {return delegate.execute();}Overridepublic void cancel() {delegate.cancel();}Overridepublic boolean isCanceled() {return delegate.isCanceled();}SuppressWarnings(CloneDoesntCallSuperClone) // Performing deep clone.Overridepublic CallT clone() {return new ExecutorCallbackCall(callbackExecutor, delegate.clone());}Overridepublic Request request() {return delegate.request();}Overridepublic Timeout timeout() {return delegate.timeout();}}
六Retrofit如何实现线程切换
ExecutorCallbackCall代理类发起请求后在响应回调中通过callbackExecutor.execute切换到主线程。
这里的callbackExecutor是Retrofit在构建时配置的
public Retrofit build() {Executor callbackExecutor this.callbackExecutor;if (callbackExecutor null) {callbackExecutor platform.defaultCallbackExecutor();}}在Retrofit的Platform中Android平台默认返回一个MainThreadExecutor在MainThreadExecutor的execute方法中线程通过Hanlder进行切换。
static class Android extends Platform {Overridepublic Executor defaultCallbackExecutor() {return new MainThreadExecutor();}static class MainThreadExecutor implements Executor {private final Handler handler new Handler(Looper.getMainLooper());Overridepublic void execute(Runnable r) {//通过Handler进行线程切换handler.post(r);}}
}