preface
Because the previous Android development third-party library summary article was widely shared in the exchange group, many friends asked me to recommend the corresponding function library. Thinking, since we all feel good, that also want to put their commonly used libraries to sort out, if ask me how to use the future, directly dumped the article. Ha ha ha, happy to think about it.
This article is object-oriented: Android developers with some foundation.
The general content of this article is explained from the following three aspects:
- What is Retrofit? Why Retrofit? How to use Retrofit?
- Common annotations and usage scenarios for Retrofit.
- How to set up interceptors for Retrofit.
Of course, if you feel that the content is not written well, I am not in a good state of mind, do not accept any criticism. You can you up,no can no…
All right, without further ado, Retrofit. Grab the little bench. Let’s get started. Those of you in the back, please come to the front.
What is the Retrofit?
“Retrofit,” which translates to “Retrofit,” is a name that makes it hard to think of its specific role, but the official explanation is: The Type-Safe HTTP client for Android and Java by Square is a framework developed by Square for Android web requests. The underlying framework is based on OkHttp. Retrofit making address
Why Retrofit? What are Retrofit’s advantages?
In Android development, there are many web request frameworks like Volley and Async Http Client. Why would we use Retrofit?
Why? One word description: convenient. Easy to use, easy to modify.
Benefits of Retrofit:
- Request speed is fast.
- Simple to use.
- Highly decoupled.
- Support for Rxjava.
- Support the GET/POST/PUT/DELETE/HEAD/PATCH.
Disadvantages:
- High encapsulation results in poor scalability
How to use Retrofit?
Guide package and permission application
The current version is 2.6.1 as of this writing. Go to Github to import the latest version.
implementation 'com. Squareup. Retrofit2: retrofit: 2.6.1'
Copy the code
Retrofit has a set of helper packages that can be located ResponseBody converter for example:
For example, if we need to convert objects via Gson, we need to add the following Gson conversion helper package:
implementation 'com. Squareup. Retrofit2: converter - gson: 2.6.2'
Copy the code
If we are using the Protobuf format, we need to add the Protobuf conversion helper package:
implementation 'com. Squareup. Retrofit2: converter - protobuf: 2.6.2'
Copy the code
Of course, there are a lot of ancillary packages: Guava, Jackson, JAXB, Moshi, Scalars, etc., all of which are available under Retrofit’s Retrofit-Converters package for those interested. I’ve listed it here for you to import.
Gson: compile 'com. Squareup. Retrofit2: converter - gson: 2.6.2'
Jackson: compile 'com. Squareup. Retrofit2: converter - Jackson: 2.6.2'
Moshi: compile 'com. Squareup. Retrofit2: converter - moshi: 2.6.2'
Protobuf: compile 'com. Squareup. Retrofit2: converter - protobuf: 2.6.2'
Wire: compile 'com. Squareup. Retrofit2: converter - wire: 2.6.2'
Simple XML: compile 'com. Squareup. Retrofit2: converter - simplexml: 2.6.2'
Scalars (primitives, boxed, and String): compile 'com. Squareup. Retrofit2: converter - scalars: 2.6.2'
Copy the code
Declare network request permissions in androidmanifest.xml. Add the following code to apply for network request permissions.
<uses-permission android:name="android.permission.INTERNET" />
Copy the code
All right, now that we’re done, let’s start with how to use it.
Steps to use Retrofit
Here we directly use the official example to do the demonstration:
- Step 1: Define the interface.
public interface IGitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
Copy the code
- Step 2: Create the cast object.
Public class Repo {... // Other attributes private String name; public StringgetName() {
returnname; }}Copy the code
- Step 3: Construct a Retrofit object.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
IGitHubService service = retrofit.create(IGitHubService.class);
Call<List<Repo>> listRepos = service.listRepos("aserbao");
Copy the code
- Step 4: Execute the request. Enqueue is asynchronous, execute is synchronous. Exactly the same as OkHttp.
listRepos.enqueue(new Callback<List<Repo>>() { @Override public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) { updateUi(response.body()); Override public void onFailure(Call<List<Repo>> Call, Throwable t) {}});Copy the code
Of course, there are some special cases, which are also mentioned here:
When the characters in the created fixture are not available, we can use the Annotations to address this problem. For example, if a json return field returns a private property, as we all know, private does not work as a property name in Android. It can be done like this:
@com.google.gson.annotations.SerializedName("private")
private boolean privateX;
Copy the code
Ok, the next introduction to the use of Api, Api use of the official introduction is also quite detailed, here is a brief introduction.
Retrofit annotations
In the above use case we used two annotations, @get and @path. What are they for? Are there any other annotations? Let’s take a look at the many annotations in Retrofit and how they work.
The first type: network request annotations
Annotations for web requests, such as @get annotations for GET requests and @POST annotations for Post requests. Similarly @put, @delete, @head (common). Same effect. Not much.
Of course, there is a special annotation in the web request annotation: @http, which is a kind of fender that can be configured to use the above request while extending it. For example, if we configure a Get request via @http and configure the body, we could configure it like this:
@HTTP(method = "GET",path = "{user}/repos", hasBody = true)
Call<List<Repo>> listRepos3(@Path("user") String user);
Copy the code
Of course, if you don’t know how to use it, go directly to the SOURCE code of the HTTP interface and see the specific use case in the comments.
There are three markup annotations in Retrofit, which are: @formurlencoded, @multipart, and @Streaming.
- @Formurlencoded: When a method is marked by @Formurlencoded, it sends Form data. And each key-value pair is annotated with the @field annotation, which contains the name and the object providing the value. Here’s how to use it (lazy here, straight from the official case) :
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
Copy the code
- @multipart: Multiple requests can be processed separately. Annotate the request with @part. Here are two examples: for example, we need to upload a file at the same time, also need to pass a background name field, in this case we can write:
@POST("/file")
@Multipart
Observable<DataResponse<UploadBean>> uploadFile(@Part("file\"; filename=\"aserbao.png\"") RequestBody file, @part ("name") RequestBody nickName);
Copy the code
Of course, @multipart can also upload multiple files at once by adding multiple upload information to @PartMap. For example, we need to upload all the images in the aserbao/ IMgs directory. We can do this.
@Multipart
@POST("/files")
Call<UploadBean> uploadFiles(@PartMap Map<String, RequestBody> params);
String aserbao_path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/aserbao/imgs/";
File file1 = new File(aserbao_path);
if(! file1.exists())return;
Map<String, RequestBody> partMap = new HashMap<>();
for (File file : file1) {
RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
partMap.put("file\"; filename=\"" + file.getName() + "\" ", fileBody); }...Copy the code
- @ Streaming: Stream tag, when we process the request to download a large file, usually can be marked with this annotation. The main function is to process the returned response body. When we write the storage file, we do not need to convert the returned content into byte[], but can directly use response.body().source() to write.
Class 3: Network request parameter annotations
This kind of annotation is also the most used kind, let’s learn about it together:
- @header, @headers: the former is used to add a request Header, the latter is used to add a non-fixed request Header. The difference is that the former works on parameters and the latter works on methods. Of course, we can also use @headerMap if multiple headers are set.
// @header applies to @get ("user")
Call<User> getUser(@Header("Authorization"$authorization_headers ($authorization_headers, $authorization_headers, $authorization_headers, $authorization_headers)"Accept: application/vnd.github.v3.full+json"."User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username); // @headermap adds a request header @get ("user")
Call<User> getUser(@HeaderMap Map<String, String> headers)
Copy the code
- @body: In POST/PUT requests, you can use the @body annotation to specify the object as the Body of the HTTP request.
@POST("users/new")
Call<User> createUser(@Body User user);
Copy the code
It is important to note that when no converter is added, the object for the @body annotation can only be a RequestBody.
- @field, @fieldMap: Used to submit fields on POST/PUT requests. These two methods are used in the @Formurlencoded tag methods to provide key-value pairs for sent forms. The former represents a key-value pair, while the latter represents multiple key-value pairs.
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
Copy the code
- @Part,@PartMap: These methods are used to submit fields in POST/PUT requests. The difference between @field and @fieldMap is that: @field, @fieldMap are used within the methods of the @@formurlencoded tag, while @Part, @Partmap are used within the methods of the @multipart tag.
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Copy the code
- @path: Specifies parameter replacement.
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
Copy the code
Here, when we call the method listRepos(“aserbao”), the values in @get will become users/aserbao/repos
- @query, @queryMap: used to add Query parameters. The former adds a single, while the latter adds one or more key-value pairs.
@GET("/user/test")
Call<Test> testQuery(@Query("id") String id);
Copy the code
Call testQuery(15). The values in @get are /user/test? id=15
- @url: The tag used to pass the Url. The following two ways are the same.
@GET("https://api.github.com/users/aserbao/repos")
Call<List<Repo>> listAbsRepos();
@GET
Call<List<Repo>> listAbsRepos(@Url String url);
Copy the code
The url configuration
Retfoit annotations have a value argument, such as @get (“users/{user}/repos”). Of course, the value parameter plays a different role for different baseUrl configurations.
Continue to take the above example, we have to request the url https://api.github.com/users/aserbao/repos, for example, how we can configure?
The first option is to add only host (https://api.github.com/) to baseUrl, with the following arguments specified in the @get annotation.
Just take the code from the example above.
new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build()
.create(IGitHubService.class)
.listRepos("aserbao");
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
Copy the code
The second: we add https://api.github.com/users/ in the baseUrl, at the back of the parameters can also be added to the values.
new Retrofit.Builder()
.baseUrl("https://api.github.com/users/") // Note the addition of/at the end. .build() .create(IGitHubService.class) .listRepos("aserbao");
@GET("{user}/repos")
Call<List<Repo>> listRepos2(@Path("user") String user);
Copy the code
Third: we can put the request link directly inside the parameter. .
new Retrofit.Builder()
.baseUrl(""Build ().create(igithubservice.class).listabsrepos (); @GET("https://api.github.com/users/aserbao/repos")
Call<List<Repo>> listAbsRepos();
Copy the code
The above three situations, in the actual project development process we use more or the first one.
Special note: baseUrl add link end must add/symbols, or you will quote Java lang. IllegalArgumentException: baseUrl must end in/exception.
How do I set up interceptors for Retrofit?
It is a necessary step to set up request interceptor at the time of request, which can not only let us clearly understand the request content, but also quickly locate the problems encountered in the process of request. You can also add generic parameters and header fields by intercepting requests.
So how do you set up a request blocker for Retrofit? As mentioned earlier, Retofit actually shipped Okhttp with a high degree of encapsulation, and Retrofit is configured as Okhttp is configured. Of course, those interested in learning more about Okhttp can refer to my other article, the HTTP Web request library Okhttp, which covers everything.
All right, without further ado, let’s take a look at how Retrofit sets up interceptors.
The steps are as follows:
- Step 1: Create an interceptor, where we print the basic information of the request.
class LoggingInterceptor implements Interceptor {
@Override public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Log.e(TAG, String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
okhttp3.Response response = chain.proceed(request);
long t2 = System.nanoTime();
Log.e(TAG, String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
returnresponse; }}Copy the code
- Step 2: Create an OkHttpClient and configure the interceptor.
OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(15, Timeunit.seconds) // Add OkHttp3's interceptor. AddInterceptor (new LoggingInterceptor()).writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS) .build();Copy the code
- Step 3: Accessorize Retrofit with OkHttpClient via client method.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.baseUrl("https://api.github.com/users"). AddConverterFactory (GsonConverterFactory. The create ()). The client (okHttpClient) / / configuration okHttpClient. The build ();Copy the code
In the example above, let’s look at the interception effect after the request is executed:
11-24 10:05:12. 023, 4671-4690 / com. Example. Baseandroidframework E/RetrofitActivity: Received the responsefor https://api.github.com/users/aserbao/repos in2495.2 MS Date: Tue, 26 Nov 2019 01:36:31 GMT Content-Type: Application /json; charset=utf-8 Transfer-Encoding: chunked Server: GitHub.com Status: 200 OK X-RateLimit-Limit: 60 X-RateLimit-Remaining: 59 X-RateLimit-Reset: 1574735790 Cache-Control: public, max-age=60, s-maxage=60 Vary: Accept ETag: W/"58bffa073ed17b36ffb324dd04f66539"
X-GitHub-Media-Type: github.v3; format=json
Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type
Access-Control-Allow-Origin: *
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Frame-Options: deny
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
Content-Security-Policy: default-src 'none'
Vary: Accept-Encoding
X-GitHub-Request-Id: D99C:7F00:4DADB:61266:5DDC819D
Copy the code
All right, we’re done. We configure the interceptor and that’s it.
So, that’s the end of Retrofit, and a quick summary
conclusion
Let me start by reviewing the general content of this article, which covers three aspects of Retrofit:
- What is Retrofit? Why Retrofit? How to use Retrofit?
- Common annotations and usage scenarios for Retrofit.
- Talked about how to set up interceptors for Retrofit.
As you can see from the article, RetrofitAPI is not much, as it is officially a highly packaged library of OkHttp.
Well, this article is about to end here, if you have any questions or do not understand this article, welcome to leave a message to me. Of course, if you want to systematically learn Android and improve Android technology friends, you can pay attention to my personal public account “Aserbaocool”, add group discussion, learn and exchange Android together.
References to this article
- Retrofit making address
- Retrofit official documentation