preface
There are many open source libraries on the web, such as Volley, Okhttp, Retrofit, etc. These three libraries are popular right now. Among them, OkHTTP and Retrofit were developed by the Square team. For the differences between these three libraries, move onstackoverfloworzhihuLook at it. What kind of open source library to choose during the development process needs to be made by our APP. Here’s a quote from StackOverflow.
As stated above, when we need to communicate with Web Services, we use Retrofit.Baidu Encyclopedia Web Service introductionSo let’s take a look at Retrofit.
What is a retrofit
In terms of what retrofit is,Official documentThere is a sentence above us. A type-safe HTTP client for Android and Java. Well, it seems that everything is a type-safe HTTP client library. So what is type safety? Type-safe code refers to access to authorized memory locations. For example, type-safe code cannot read values from private fields of other objects. It can only be read from a well-defined allowed access type. Type-safe code has well-defined data types. More contentBaidu Encyclopedia – Type safetyHere also quote a sentence from zhihu above.
RESTful- Baidu Encyclopedia
Rest – Baidu Encyclopedia
So many abstract concepts above are too abstract for us to care about them. All we need to know is that Retrofit is a really good open source library.
Introduction to Tiger fighting
Open source libraries are nice, but you can’t document in more detail. Entry is a big tiger. How can I say, the documentation is nice, but it doesn’t work. So, let’s look at the concrete, real steps to get started.
1. Add it in the Gradle script
The compile 'com. Squareup. Retrofit: retrofit: 2.0.0 - beta 2' compile 'com. Squareup. Retrofit, the converter - gson: 2.0.0 - beta 2'Copy the code
Retrofit is a useful OKHTTP in retrofit, and the Gson library was added to convert returned data into entity classes.
2. Convert the HTTP API into a Java interface
Let’s call this an HTTP interface and let’s say we want to go to this site and get json data. Api.github.com/users/Guole… You can also replace Guolei1130 with your own Github.
public interface gitapi {
@GET("/users/{user}")
Call getFeed(@Path("user") String user);
}Copy the code
@get (” STR “), indicating that the request address is BASEURL+STR, {user}, which will later be replaced by the user parameter of getFeed, concatenating the final request path. What’s the data room back there. Call< gitModel >, where the Call returned is used to execute the request. Note that Call< T> represents data in the return body. Let’s look at the return data from the url above.
, is obviously a JSON object.
Call< List< gitModel >> Call< List< gitModel >> Call< List< gitModel >> Call< List< gitModel >> With the Call < gitmodel >. More do not say, oneself experience experience.
3. The preparation of the model
You just need to write the key value of the JSON object, write the corresponding member variable of model, and generate the get set method.
As shown in figure:
4. Execute the request
Retrofit retrofit= new Retrofit.Builder() .baseUrl("https://api.github.com") .addConverterFactory(GsonConverterFactory.create()) .build() gitapi service = retrofit.create(gitapi.class) Call model = service.getFeed("Guolei1130") model.enqueue(new Callback() { @Override public void onResponse(Response response, Retrofit retrofit) { Log.e(TAG, "onResponse: "+response.body().getLogin() ) } @Override public void onFailure(Throwable t) { Log.e(TAG, "onFailure: " + t.getMessage()) } })Copy the code
Here we construct the Retrofit object first. Since we convert the returned JSON data into a Model object, we use addConverterFactory to add a converter when we construct the Retrofit object.
The Call object is then generated using the methods of the HTTP interface, and the Call object is finally used to perform the HTTP request (asynchronous and synchronous, described below). Don’t forget to add permissions.
All right, we shot the tiger as soon as we got here.
Notes cool
Now that we know retrofit uses annotations to convert HTTP into a Java interface, we need to know what annotations are available and how to use them.
Request way
GET, POST, PUT, DELETE, and HEAD are the ones we usually use in development. I won’t go into HTTP requests here, but there are many articles on the web that describe the HTTP protocol in great detail.
We know the get request, where the parameters are placed in the path. Look at the path below.
.
Isn’t that long, but it doesn’t matter, you can splice that long into a path with Retrofit, how do you do that?
Here we use @Query (a key-value pair) and @QueryMap (multiple key-value pairs).
@GET("/s")
Call onekey(@Query("wd") String wdvalue);Copy the code
The code above concatenates = “baidu.com/s?wd=wdvalu… When there is only one parameter above, and many times we have many parameters, we need to use @QueryMap
Call manykey(@QueryMap Map options);Copy the code
The above concatenates multiple key-value pairs into a path.
Request body
We know that one of the differences between POST and GET is the placement of parameters, get in the URL path and POST in the request body. Attention: high energy ahead, please read carefully. High energy ahead, please read carefully. High energy ahead, please read carefully. Let’s simulate a login where the request parameters are username and password and the return parameters are our username.
1. Convert it to an interface
@POST("/index.php")
Call post(@Body User user);Copy the code
2. Write User and Des to convert data
public class Des { public String des; public String getDes() { return des; } public void setDes(String des) { this.des = des; }}Copy the code
public class User { public String username; public String password; public User(String username,String password){ this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}Copy the code
3. Send the request
New retrofit.builder () //.baseurl ("https://api.github.com").baseurl ("http://192.168.1.214") .addConverterFactory(GsonConverterFactory.create()) .build() gitapi service = retrofit.create(gitapi.class) Call model = service.post(new User("guolei","123456")) model.enqueue(new Callback() { @Override public void onResponse(Response response, Retrofit retrofit) { Log.e(TAG, "onResponse: "+response.body().getDes()) } @Override public void onFailure(Throwable t) { Log.e(TAG, "onFailure: "+t.getMessage() ) } })Copy the code
The client-side code is very simple and won’t be explained too much here. The focus is on the interaction between the client and the server. Damn it, you screwed me. There is a sentence in the official document that says so.
$_POST[‘ username ‘] = $_POST[‘ username ‘] = $_POST[‘ username ‘]; Take the tools out and analyze them.
Bag grab CharlesI’m not going to talk about how to use it, I’m just going to talk about how to set up the Android proxy. Press and hold the linked Network – modify Network – to set the proxy to manual and enter the IP address and port number. The diagram below:
.
Next, we use the packet capture tool to look at the data received by the server. The diagram below:
.
Sure enough, it’s JSON data, but we obviously feel like we can’t receive this data with $_POST. How to do, don’t worry, we can receive through the following code. The complete PHP code is as follows (ps: demo, few lines)
$des);
echo json_encode($arr);
Copy the code
Well, so little, about the following installation of the PHP development environment will not say, so easy is not it. Finally, let’s take a look at the effect:
Form encoding and multi-part
What is a form? I think we all know that there are many elements in a form, and we are no exception here. In HTML code, we often submit via a form form. In the request body above, we clearly feel that the thing looks a bit difficult to use. But that’s okay, we have the form. It’s the same as the last example.
@FormUrlEncoded
@POST("/index.php")
Call form(@Field("username") String username,@Field("password") String password);Copy the code
Call model = service.form("guolei","123456");Copy the code
Look at the output;
What is this multi-part, which is to divide the request into multiple parts, there is nothing to say about this.
Request header
We know that HTTP has a request header, and sometimes we need to fill in or configure the request header, for example, file upload, or cookie retention. The request header here supports both dynamic and static configuration.
1. Static configuration
Annotated by @headers. The following paragraph is from the official document.
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})Copy the code
2. Dynamic configuration
Let’s have a copy of the official document.
@GET("/user")
Call getUser(@Header("Authorization") String authorization)Copy the code
This is all relatively simple, not much to talk about, and in fact, there aren’t many places we need to configure headers during development.
Implement way
Asynchrony and synchronization are supported. We used asynchrony in the above examples. So let’s take a look at how to perform a synchronous request, which is also very simple.
Model.execute ().body().getLogin()Copy the code
Obfuscated code
-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keepattributes Signature
-keepattributes ExceptionsCopy the code
retrofit+rxjava
In the parabolic big RxJava primer, we learned that Retrofit and RxJava can be used together, so let’s now look at how.
Add 1.
dependencies { compile fileTree(dir: 'libs', include: [' *. Jar ']) testCompile junit: junit: '4.12' compile 'com. Android. Support: appcompat - v7:23.0.1' compile 'com. Squareup. Retrofit: retrofit: 2.0.0 - beta 2' compile 'com. Squareup. Retrofit, the converter - gson: 2.0.0 - beta 2' compile 'the IO. Reactivex: rxjava: 1.0.16' compile 'IO. Reactivex: rxandroid:' 1.0.1 compile 'com. Squareup. Retrofit: adapter - rxjava: 2.0.0 - beta 2'}Copy the code
2. The HTTP API interface
@FormUrlEncoded
@POST("/index.php")
public Observable rxpost(@Field("username") String username,@Field("password") String password);Copy the code
3. Add RxJavaCallAdapterFactory to Retrofit
Retrofit retrofit= new Retrofit.Builder() // .baseUrl("https://api.github.com") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) BaseUrl (" http://192.168.1.214 "). The build ()Copy the code
4. Perform
gitapi service = retrofit.create(gitapi.class)
Observable observable = service.rxpost("quanshijie", "123456")
observable.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(new Action1() {
@Override
public void call(Des des) {
Log.e(TAG, "call: " + des.getDes().toString())
mText.setText(des.getDes().toString())
}
}, new Action1() {
@Override
public void call(Throwable throwable) {
Log.e(TAG, "call: " + throwable.getLocalizedMessage())
}
})Copy the code
Here we have to do a good job of thread scheduling, now the network of bad code, one line less code, pit me for a long time. Meow. Finally, take a look at the renderings.
conclusion
To this point, we still need other requirements of network request, such as file upload and download, cookie retention, HTTPS protocol support and so on. In Okhttp, all of these things are ok, retrofit being Okhttp’s cousin, I think it’s not too bad, you have to keep learning. However, after checking some information, we know that the choice of network library should be based on the demand, and it is obviously impossible to use a network library for a large project. Okhttp + Retrofit + image cache + RXJava will become the mainstream of future development. Hope so. I’m so tired. I haven’t eaten yet. Retrofit has its flaws. I’m guessing the last three holes are bigger. Cut it out. Call it a day.