码迷,mamicode.com
首页 > 其他好文 > 详细

Retrofit2 source

时间:2016-05-10 07:10:59      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:

本来一开始是用中文写的,写着写着,可能写代码写多了,赶脚英文好亲切,就换成英文了,

这也是我第一次写英文博客,曾经感觉遥不可及,but ,现在我也可以做到,哈哈哈哈,当然参考了白大神的博客,明天在整理一下,就酱,

欢迎各位大神指点~~~感激不尽

How to use it

Trilogy

create the Call interface. Like this @GET()Call <List<Bean>> contributors @Path("") String **;

create a retrofit object .

Retrofit retrofit = new Retrofit.Builder()

                          .baseUrl(API_URL)

                          .addConverterFactory(GsonConverterFactory.create())

create an Github object(using retrofit object)

To get the data(using github)


To compare with volley

volley:http request -> create a request object - > runing -> RequestQueue -> NetworkDispatcher Request to the server for data

create a request(include method,url,url param,success listener ande fail listener)

Put the request in the requestQueue

NetworkDispatcher Request to the server for data


volley Can be encapsulated into retrofit



principle

Dynamic proxy (compared to the request of the volley and implementation, can understand the retrofit using interface to request)

Github github = retrofit.create(Github.class);

Descendants through retrofit object making the class object of the interface,return github object

Enter the create method:

 @SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
  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 {http://write.blog.csdn.net/postedit/51356768
            // 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 serviceMethod = loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

create() returns a Dynamic Proxy objects


What‘s the Dynamic Proxy

是这样一种类:它是在运行时生成的class,在生成它时必须提供一组interface给它,然后该class就宣称它实现类这些interface

Such as you want to perform an operation before judge whether this user login, or to determine the account how much money before payment

why use it?

just see that,

Call<List<Contributor>> call = github.contributors("square", "retrofit");

github -> Dynamic Proxy,It not a true Github interface implements object..

when github object call contributors method, execution is the Dynamic Proxy method

You look is to call the method of contributors,actually the Retrofit in fact at this time interface into an HTTP request, -> the  MethodHandler object


The MethodHandler object include

OkHttpClient: send the request of the tool

RequestFactory: similar to the Request of Volley, contains the urls, the HTTP Request Header information, MediaType, Method and RequestAction array

CallAdapter: HTTP request returns the type of dataThe (RxJava)

Converter: data ConverterWen


Trilogy

Call<List<Controbutor>> call = github.contributors(....)  ->  generate an Http request

call.enqueue ->send the request

handle the Response data


Source code analysis

composition

  1. retrofit2.http
  2. interface and class

The retrofit take over all this part of the function network request okHttp

interface

  • Callback<T>:
    • The request data returned by the interface
    • tow method
      1. void onResponse(Response<T> response);
      2. void onFailure(Throwable t)
  • Converter<F,T>:
    • HTTP return data parsed into Java objects. Such as xml,Gson,protobuf....
    • tip: Create Retrofit object added as you need to use the Converter to realize. Such as addConverterFactory(GsonConverterFactory.create())
  • Call<T>
    • send the HTTP request, like HttpStack(Volley) Interface design ideas
    • Retrofit the default implementation is OkHttpCall< T >
    • you can implement your own Call class according to actual condition
    • subclasses can be implemented based on HttpClient or HttpUrlConnetction HTTP request tool
  • CallAdapter<T>
    • an attribute -> responseType
    • an function -> <R> T adapter(Call<R> call)
    • an class implement -> DefaultCallAdapter: To convert the Call object to another object,such as rxjava

Run

return an Dynamic Proxy object: Github github = retrofit.create(Github.class)

return an OkHttpCall object: Call<List<T>> call = github.contributors("...","...")

You got the Call object to perform HTTP requests

contributors

When performing the contributors(): the Retrofit is carried out dynamic proxy InvocationHandler object, finally Will eventually create a MethodHandler object

static MethodHandler<?> create(Retrofit retrofit, Method method) {
    CallAdapter<Object> callAdapter = (CallAdapter<Object>) createCallAdapter(method, retrofit);
    Type responseType = callAdapter.responseType();
    Converter<ResponseBody, Object> responseConverter =
        (Converter<ResponseBody, Object>) createResponseConverter(method, retrofit, responseType);
    RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);

    return new MethodHandler<>(retrofit.client(), requestFactory, callAdapter, responseConverter);
}

MethodHandler

an MethodHandler include four object

  1. OkHttpCliet
    • The default
  2. RequestFactory
    • Through RequestFactoryParser. parse (methord, responseType,retrofit) main effect is all the data parsing the Http request
    • Main principle is to parse an interface, such as the dead simple interface, the result is get the whole Http request all the information, can also through @ Path and @ Query annotation splicing Url
  3. CallAdapter
    • Create a Retrofit object, add the CallAdapter you want, and get CallAdapter way is also obtained from the Retrofit object
  4. Converter
    • private static Converter<ResponseBody, ?> createResponseConverter(Method method,
        Retrofit retrofit, Type responseType) {
        Annotation[] annotations = method.getAnnotations();
        try {
          return retrofit.responseBodyConverter(responseType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
          throw Utils.methodError(e, method, "Unable to create converter for %s", responseType);
        }
      }
      


purpose

Object invoke(Object ... args){

return callAdapter.adapt(new OkHttpCall<>(client,requestFactory,responseConverter,args));}

This is dead simple. Contributors (" square ", "retrofit");Return to the Call object


Synchronous or asynchronous

finally you call Call object of the execute() or enqueue(Callback<T> callback) ,you can send an Http request


cache

Retrofit will cache the parsed request, is on the Map "Method, MethodHandler <?> > methodHandlerCache this object


Finally

Retrofit use annotations to describe an HTTP request

a HTTP request abstract into a Java interface,

and then use the Java dynamic proxy approach

dynamic to the interface of annotations "translate" into an HTTP request,

and then execute the HTTP request


retrofit  dependent on Java reflection, such as abnormal capture, throwing and processing,

and a large number of Factory design pattern

This code is good code is dependent on the interface rather than to realize the best example


Retrofit2 source

标签:

原文地址:http://blog.csdn.net/zhaoyazhi2129/article/details/51356768

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!