Retrofit source Code Interpretation (I)–Retrofit simple process

Labels (separated by Spaces) : Retrofit source study notes


Retrofit

It’s not a web request framework, it’s a wrapper around the web request framework, it’s a facade class, it’s a portal to the whole framework, and we can configure our requests through this method by using an internal class called Builder, which is created using the Builder pattern, and one of the important variables in it is ServiceMethod

ServiceMethod

Corresponding to the method in our written interface class, through the dynamic proxy pattern, through which we can define the method (including method parameters, annotations) into a HTTP request. ServiceMethod also helps us parse annotations in methods to generate Request objects. Three important factory classes, CallAdapter factory and Converter factory, are generated in the ServiceMethod class

  • The CallAdapter factory encapsulates network requests as OKHttpCall by default. The purpose of this factory is to translate OKHttpCall into a resolution suitable for different platforms (e.g. Java8,ios, Android).
  • The Converter factory is used for production data conversion, which by default converts the Response object returned by OKHTTP into our Java object for use. In Retrofit, the default is to use Gson to parse data
  • The CallFactory factory is used to create the Call request class. HTTP requests are abstracted and encapsulated into the Call class, indicating that the request is ready to run

In this case, through the creation and coordination of these factory classes, OkHttpCall requests can be created, which can be synchronous or asynchronous requests. It can be seen that Retrofit is only a layer of encapsulation of OkHttpCall, and the bottom layer is okHTTP network requests.

When an OkHttpCall request is made, it will convert the okHttpCall to be used by different platforms through the CallAdapter factory created by the ServiceMethod.

The data is then converted to a Response object through the Converter, and then the thread is switched through the callbackExecutor (the child thread requests the data, and the main thread updates the UI). Of course, this is only for asynchronous requests. Synchronous requests do not require this.

Simple use

Request process

The first thing to make sure is that Retrofit is a wrapper tool class for the Web request framework, not a web request framework. It uses okHTTP as the underlying web request framework, but it’s a deeper wrapper on top of OKHTTP to make it easier to use. So the flow is

App->Retrofit: Send requests



Retrofit-->App: data (parse well)



Retrofit->OkHttp: I'm going to request data



OkHttp-->Retrofit: Request good data to return



OkHttp->Server: background, give me the data



Server-->OkHttp: Here you are

Copy the code
  • App applications request the network through Retrofit, essentially encapsulating the request parameters and HTTP methods using the Retrofit interface layer, and then forwarding subsequent network requests to OkHttp
  • After the server returns the data,OkHttp gives the raw results to Retrofit, which parses the data according to the user’s needs and then performs the relevant logic

Code demo

Example a
  • Retrofit turns your HTTP API into a Java interface.
Public interface GitHubService {// @get GET request method // users/{user}/repos So this curly bracket, which means that the argument inside is dynamic and can be changed is the value of @Path("user") String user this passed in user@get ("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}
Copy the code
  • The Retrofit class generates an implementation of the GitHubService interface.
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);

Copy the code
  • Each Call from the created GitHubService can make a synchronous or asynchronous HTTP request to the remote webserver.
Call<List<Repo>> repos = service.listRepos("octocat");
Copy the code
repos.enqueue(new Callback(){@override public void onFailure(Call Call,IOException e){@override public void onResponse(Call Call,IOException e) Throws IOException{// This is a request for successful data only}})Copy the code

The above code demo is a simple example from the official website click here

Example 2

1. Add network permissions

 <uses-permission android:name="android.permission.INTERNET"/>
Copy the code

2. Create an accepted return type

class HttpResult<T> { private int count; private int err; private int total; private int page; private int refresh; // Use to imitate Data private T items; } class TestBean{ private String format; private long published_at; private String content; private String state; } public class User { /** * avatar_updated_at : 1418571809 * uid : 13846208 * last_visited_at : 1390853782 * CREATED_AT: 1390853782 * state: active * last_device: Android_2.6.4 * role: n * login: -- 13846208 * icon : 20141215074328.jpg */ private int avatar_updated_at; private int uid; private int last_visited_at; private int created_at; private String state; private String last_device; private String role; private String login; private int id; private String icon; }Copy the code

3. Create a service interface

Public interface TestInterface {// Each method argument needs to be annotated or it will GET an error."article/list/latest? page=1")
    Call<HttpResult<List<TestBean>>> getQiuShiJsonString();

}

Copy the code

4. Create a Retrofit instance

 public static Retrofit getRetrofit() {

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(10, TimeUnit.SECONDS);


        returnNew retrofit.builder ().client(builder.build()) // Set the URL to request the network address (base address this address must be"/"Public Builder baseUrl(HttpUrl baseUrl) {public Builder baseUrl(HttpUrl 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;
    //}
                .baseUrl("http://m2.qiushibaike.com/"). AddConverterFactory (GsonConverterFactory. The create ()) / / set the default data parser Gson AddCallAdapterFactory (RxJavaCallAdapterFactory. The create ()) / / set support RxJava converter. The build (); }Copy the code

5, create the network request interface instance

   TestInterface service = getRetrofit().create(TestInterface.class);
Copy the code

6. Create the call method from the interface instance

 Call<HttpResult<List<TestBean>>> qiuShiJson = service.getQiuShiJsonString();
Copy the code

7. Perform asynchrony (or synchronous) via call

 qiuShiJson.enqueue(new Callback<HttpResult<List<TestBean>>>() {
            @Override
            public void onResponse(Call<HttpResult<List<TestBean>>> call, Response<HttpResult<List<TestBean>>> response) {
                Log.d("TestRetrofit"."Requested back data");
                if (response.isSuccessful()){
                    HttpResult<List<TestBean>> body = response.body();
                    Log.d("TestRetrofit"."body.getSubjects().size():" + body.getSubjects().size());
                }
            }

            @Override
            public void onFailure(Call<HttpResult<List<TestBean>>> call, Throwable t) {
                Log.d("TestRetrofit"."Data request failed, reason for failure"+ t.getMessage()); }});Copy the code

The project address

Source code review and summary of the open source Project Retrofit