What is the Retrofit

Retrofit is a type-safe HTTP client that supports Android and Java. It is an open source project from Square, currently in version 2.0.

In actual development, we use Retrofit in conjunction with OKHTTP. We use OKHTTP as the transport layer and Retrofit to describe our HTTP protocol using a Java interface on top of OKHTTP. Simply put: Using Retrofit to convert the HTTP API protocol into a Java Interface service, it would be much easier for us to use Java classes directly.

Making: github.com/square/retr…

Current version 2.1, this article will compare 1.9 to describe 2.x features.

Retrofit characteristics

  • Retrofit converts HTTP apis into Java interfaces and generates default implementation classes for the interfaces.
  • Supports synchronous and asynchronous invocation
  • Use annotations to describe HTTP requests
  • Object conversion, such as from JSON to Java objects
  • Supports Multipart request body and file upload

Class libraries and references

Add the dependent

Add this to your app-level Gradle:

The compile 'com. Squareup. Retrofit2: retrofit: 2.1.0'Copy the code

In general, we also need to process json data, so we need a converter, and you need to add the following dependencies:

The compile 'com. Squareup. Retrofit2: converter - gson: 2.1.0'Copy the code

Integrated OKHTTP

To avoid repeated references to OKHTTP, you can also use:

The compile (' com. Squareup. Retrofit2: retrofit: 2.1.0 ') {/ / eliminate dependence okhttp exclude the module: 'okhttp'} the compile 'com. Squareup. Okhttp3: okhttp: 3.3.1' / / dependence okhttp againCopy the code

Integrated rxJava

If you want to work with rxJava, you need to add dependencies:

The compile 'com. Squareup. Retrofit2: adapter - rxjava: 2.1.0' compile 'IO. Reactivex: rxandroid: 1.0.1'Copy the code

In RetroFIT2.x, RestAdapter is changed to Retrofit

Written in Retrofit 1.9

RestAdapter.Builder builder = new RestAdapter.Builder();  
Copy the code

Retrofit 2. X

Retrofit.Builder builder = new Retrofit.Builder();  
Copy the code

Configuring the URL

Basic BaseUrl

The base URL, which is the address of your server, is usually a domain name. For example, if you want to visit www.xxxx.com/user/list and we use a relative URL for development, that is /user/list, then its baseUrl will be www.xxx.com.

Retrofit retrofit = Retrofit.Builder()  
    .baseUrl(API_BASE_URL);
    .build();

YourService service = retrofit.create(YourService.class);  
Copy the code

Retrofit recommends that we end our baseUrl with a “/”. So we don’t have to write “/” when we specify relative paths. Something like this:

Public interface UserService {@post ("me") // Call<User>me(); } Retrofit retrofit = Retrofit.Builder() .baseUrl("https://your.api.url/v2/"); // Notice here, ending with a slash. Build (); UserService service = retrofit.create(UserService.class); // the request url for service.me() is: // https://your.api.url/v2/meCopy the code

A dynamic url

Sometimes we get a url in some other way, such as reading a url from a database or network, which cannot be combined with a baseUrl and relative url as above. We can do this with the @url annotation, which annotates the parameters of a method to indicate that it is a Url. Example:

public interface UserService {  
    @GET
    public Call<File> getZipFile(@Url String url);
}
Copy the code

An Interceptors powered by OKHTTP

Interceptors are a useful way to handle custom requests. 2. Define an OkHttpClient, call addInterceptor, and pass in Interceptor 3. When building Retrofit, in retrofit.Builder, use the.client() method. Pass an example of OkHttpClient:

OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); httpClient.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request original = chain.request(); // Customize the request Request request = original.newBuilder() .header("Accept", "application/json") .header("Authorization", "auth-token") .method(original.method(), original.body()) .build(); Response response = chain.proceed(request); // Customize or return the response return response; }}); OkHttpClient client = httpClient.build(); Retrofit retrofit = Retrofit.Builder() .baseUrl("https://your.api.url/v2/"); .client(client) .build();Copy the code

Invocation of the request. Synchronous and asynchronous, and termination

In Retrofit 1.x, synchronous methods require a return value in the service interface declaration, and asynchronous methods require a generic parameter of Callback as the last parameter. In 2.x, there is no longer a distinction between synchronous and asynchronous calls, and both are wrapped in a generic Call class. Let’s compare them in terms of “interface definition” and “invocation.”

The difference between “interface definition”

Retrofit 1.9

Public interface UserService {// Sync, return value @post ("/login") User login(); @post ("/login") void getUser(@query String id, Callback<User> cb); }Copy the code

In Retrofit 2.x

public interface UserService {  
    @POST("/login")
    Call<User> login();
}
Copy the code

Notice that a Call generic is returned above. 2. X no longer distinguishes asynchronous synchronous requests in terms of parameters and return values.

The difference between “call”

In Retrofit 1.9, synchronization is called directly. Asynchrony requires an implementation of the incoming callback. Ways to deal with success and failure in an implementation.

// synchronize User User = userservice.login (); Userservice. login(new Callback<User>() {@override public void success(User User, Response response) { // handle response } @Override public void failure(RetrofitError error) { // handle error } });Copy the code

In Retrofit 2.x synchronization is a call to call.execute() to get the result. Asynchrony is calling the enqueue method and passing in the callback. Note that the callbacks here are onResponse methods, as opposed to the success and failure methods above. Here is the onResponse method using response.issuccessful () to determine success and failure. If that fails, use errorBody to get the error message.

Call<User> Call = userservice.login (); User user = call.execute().body(); // Call<User> Call = userservice.login (); call.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { // response.isSuccessful() is true if the response code is 2xx if (response.isSuccessful()) {  User user = response.body(); } else { int statusCode = response.code(); // handle request errors yourself ResponseBody errorBody = response.errorBody(); } } @Override public void onFailure(Call<User> call, Throwable t) { // handle execution failures like no internet connectivity } }Copy the code

Cancel/terminate the request

There is no way to terminate a request in Retrofit 1.9. At 2.x, you can terminate the request with cancel.

Call<User> call = userService.login();  
User user = call.execute().body();

// changed your mind, cancel the request
call.cancel();
Copy the code

converter

Select the converter you need

Retrofit 2.x will no longer provide a default json converter, as opposed to 1.9 providing a default JSON converter. For example, if you want to use JSON parsing, you can use the Gson converter and add library dependencies:

The compile 'com. Squareup. Retrofit2: converter - gson: 2.1.0'Copy the code

Retrofit supports many types of converters, depending on your needs, you can reference different extension libraries via Gradle:

Gson: com. Squareup. Retrofit2: converter - Gson: 2.1.0 Moshi: com. Squareup. Retrofit2: converter - Moshi: 2.1.0 Jackson: Com. Squareup. Retrofit2: converter - Jackson: 2.1.0 SimpleXML: com. Squareup. Retrofit2: converter - SimpleXML: 2.1.0 ProtoBuf: Com. Squareup. Retrofit2: converter - protobuf: 2.1.0 Wire: com. Squareup. Retrofit2: converter - Wire: 2.1.0Copy the code

If the Converter above is not enough for you, you can customize the Converter by implementing Converter.Factory yourself.

Add a converter to a Retrofit object

We need to manually add a converter to a Retrofit object, using the addConverterFactory method to add a ConverterFactory object to Retrofit. * You can add one or more ConverterFactories depending on your needs, order is important, Retrofit will use them in order, and if that fails, try the next converter.

Example:

Retrofit retrofit = Retrofit.Builder()  
    .baseUrl("https://your.api.url/v2/");
    .addConverterFactory(ProtoConverterFactory.create())
    .addConverterFactory(GsonConverterFactory.create())
    .build();
Copy the code

Custom converter

Read Retrofit Converter Implementations

Integrated RxJava

Rely on

Retrofit 1.9 integrates three request execution mechanisms: synchronous, asynchronous, and RxJava. With 2.x, only synchronous and asynchronous mechanisms remain. Retrofit 2.x provides a plug-in extension mechanism to support RxJava. To integrate RxJava, you need to add the following two dependencies. The first is a CallAdapter that handles requests in a new way. You can use Observable as the return value of the interface declaration. The second dependency is required by the AndroidSchedulers class, which provides scheduling on the Android main thread.

The compile 'com. Squareup. Retrofit2: adapter - rxjava: 2.1.0' compile 'IO. Reactivex: rxandroid: 1.0.1'Copy the code

use

When building a Retrofit instance, the CallAdapter is passed in through the addCallAdapterFactory method.

Retrofit retrofit = new Retrofit.Builder()  
    .baseUrl(baseUrl);
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .addConverterFactory(GsonConverterFactory.create())
    .build();
Copy the code

Returns an Observable generic object when the interface is declared.

public interface UserService { @POST("/me") Observable<User> me(); } // this code is part of your activity/fragment Observable<User> observable = userService.me(); observable .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(new Subscriber<User>() { @override public void onCompleted() {@override public void onError(Throwable e) {@override public void onCompleted(Throwable e) Void onNext(User User) {// process the response result}});Copy the code

Default logs are not included

Retrofit itself does not provide logging, but we can implement it with a custom OKHTTP interceptor. You can read this article: On How to Get Back Logging into Retrofit 2

Updated feature WebSockets

Retrofit does not provide WebSockets, but OKHTTP does.

Extend resources

Jake Wharton’s Talk @Droidcon NYC 2015 on Retrofit 2 Details on OkHttp Interceptors Retrofit Converters RxAndroid on GitHub Retrofit CallAdapters Retrofit Change Log