Use of the "Android-frame" retrofit

Source: Internet
Author: User

Retrofit is an HTTP client access framework that can be applied to Android and Java by Square, and its underlying application is okhttp.

In this post, we take the following HTTP request as an example:

HTTPS://Api.github.com/users/basil2style

The result of the request (JSON) is as follows:

{  "Login": "Basil2style",  "id": 1285344,  "Avatar_url": "Https://avatars.githubusercontent.com/u/1285344?v=3",  "gravatar_id": "",  "url": "Https://api.github.com/users/basil2style",  "Html_url": "Https://github.com/basil2style",  "Followers_url": "Https://api.github.com/users/basil2style/followers",  "Following_url": "Https://api.github.com/users/basil2style/following{/other_user}",  "Gists_url": "https://api.github.com/users/basil2style/gists{/gist_id}",  "Starred_url": "Https://api.github.com/users/basil2style/starred{/owner}{/repo}",  "Subscriptions_url": "Https://api.github.com/users/basil2style/subscriptions",  "Organizations_url": "Https://api.github.com/users/basil2style/orgs",  "Repos_url": "Https://api.github.com/users/basil2style/repos",  "Events_url": "Https://api.github.com/users/basil2style/events{/privacy}",  "Received_events_url": "Https://api.github.com/users/basil2style/received_events",  ' type ': ' User ',  "Site_admin":false,  "Name": "Basil",  "Company": "Makeinfo",  "Blog": "Http://www.themakeinfo.com",  "Location": "Toronto,canada",  "Email": "[email protected]",  "Hireable":true,  "Bio": "Developer | Marketer | Reader | cinephile | Entrepreneur ",  "Public_repos": 35,  "Public_gists": 4,  "Followers": 64,  "Following": 155,  "Created_at": "2011-12-26t00:17:22z",  "Updated_at": "2016-11-12t00:58:15z"}

Let's introduce this framework from the retrofit usage to the principle.

First, the use of retrofit:

0, configure the retrofit development environment:

We need to import the retrofit package before using retrofit, this demo is developed in Android Studio, so you only need to import the dependencies in the Gradle file. The following are the dependencies of retrofit:

Compile ' com.squareup.retrofit2:retrofit:2.1.0 '

In addition, the format of the data we get from the network is different, possibly the Json/gson format, or other formats like Jackson, wire, etc., we need to use a format conversion factory converterfactory in the later encoding, So we also need to import some dependencies about the format. The Json/gson format is used in this demo, so the import dependent dependencies are as follows:

Compile ' com.squareup.retrofit2:converter-gson:2.1.0 '

Other formats require an imported dependency list as follows (the following version number is added yourself):

    gson:com.squareup.retrofit2:converter-Gson    Jackson:com.squareup.retrofit2:converter-Jackson    Moshi:com.squareup.retrofit2:converter-Moshi    Protobuf:com.squareup.retrofit2:converter- Protobuf    Wire:com.squareup.retrofit2:converter-wire simple    XML:com.squareup.retrofit2:converter-  SimpleXML    scalars (Primitives, boxed, and String): Com.squareup.retrofit2:converter-scalars

At this point, retrofit's development environment was built.

1. Create a service interface that gets data from the network:

Retrofit uses a dynamic proxy to convert a network request into an interface that allows the user to access the network only by invoking an interface. The code for this interface is as follows:

 Public Interface Retrofitservice {    @GET ("/users/basil2style")    call <InfoData> getinfodata ();}

As you can see from the code above, the value in the @GET tag is only part of the request. In general, when we make network requests, most requests are data sent from one server, so we can manage the root URLs of these requests uniformly. In this demo, I put the root URL of the network request in the Shareddata class:

 Public class shareddata {    /**     * Base Url     */public     Static Final String base_url = "https://api.github.com";}

As with other network requests, retrofit can make network requests by @GET and @POST, which sometimes require parameters and sometimes no, the Getinfodata () method above is a network request method that takes no parameters. Of course, there is also a need to create a bean class Infodata to store the data obtained from the network:

 Public classInfodata {PrivateString Login; Private intID; PrivateString Avatarurl; PrivateString Gravatarid; PrivateString URL; PrivateString Htmlurl; PrivateString Followersurl; PrivateString Followingurl; PrivateString Gistsurl; PrivateString Starredurl; PrivateString Subscriptionsurl; PrivateString Organizationsurl; PrivateString Reposurl; PrivateString Eventsurl; PrivateString Receivedeventsurl; PrivateString type; Private BooleanSiteAdmin; PrivateString name; PrivateString Company; PrivateString Blog; PrivateString location; PrivateString Email; Private Booleanhireable; PrivateString bio; Private intPublicrepos; Private intpublicgists; Private intfollowers; Private intfollowing; PrivateString Createdat; PrivateString Updatedat; //Getter, setter method}

Let me introduce you to call. Call can be used to send a request where there are two methods: Enqueue () and execute (), which is used to send an asynchronous request, which in turn sends a synchronous request, as described in code below.


2. Initialize the Retrofit object:

The code to create the retrofit object is as follows:

        New Retrofit.builder ()                . BASEURL (Shareddata.base_url)                . Addconverterfactory (Gsonconverterfactory.create ( )                . Build ();

can see that The retrofit object is created through the Retrofit.builder inner class, BaseURL is the root URL that needs to be accessed, and because the requested data is in JSON format, we can use a JSON-related conversion factory to process the data, using the same Gson conversions as JSON Factory, namely Gsonconverterfactory.

3. Call the Retrofit object for network access:

After getting to the retrofit object, we get to the network request interface Retrofitservice through this object, and then call the Getinfodata () method in it to obtain the network data. The specific code is as follows:

Retrofitservice service = Retrofit.create (retrofitservice.class); Pager<InfoData> call =Service.getinfodata (); Call.enqueue (NewCallback<infodata>() {@Override Public voidOnresponse (call<infodata> call, response<infodata>response) {Infodata Data=Response.body (); Message Message=Message.obtain (); Message.what= 1; Message.obj=data;            Handler.sendmessage (message); } @Override Public voidOnFailure (call<infodata>Call , Throwable t) {Handler.sendemptymessage (0); }        });

It also needs to be explained here that retrofit is not like volley can directly pull the asynchronous data back to the main thread, retrofit callback class Onresponse () method is still in the asynchronous thread, if we want to get the data to the main thread, Need to use Asynctask or handler, this demo is using handler, the following is the code in handler:

    PrivateHandler Handler =NewHandler () {@Override Public voidhandlemessage (Message msg) {Switch(msg.what) { Case1: Infodata Data=(Infodata) msg.obj; Toast.maketext (mainactivity. This, Data.getblog (), Toast.length_short). Show ();  Break;  Case0: Toast.maketext (mainactivity. This, "Get Data Failed", Toast.length_short). Show ();  Break; }        }    };

So far retrofit access to the network to get the data demo is complete, the results are as follows:


Two, Retrofitservice interface method type:

The Getinfodata () method in the Retrofitservice interface above is just a GET request with no parameters, we sometimes need to use a POST request when accessing the network data, and may carry some parameters, etc. Here's a look at how the interface methods are written in these cases.

Special Note: The interface below is not related to the interface in the demo above, and there is no relationship between 22!

1. Get request with no parameters:

    @GET ("Users/list")    call <List<User>> getuserlist ();

2. Get request with Parameters:

(1) The first way: add parameters to the get tag:

    @GET ("Users/list?sort=desc")    call <List<User>> getuserlist ();

(2) The second way: Set parameters in the method parameters:

    @GET ("Users/list")    call <List<User>> getuserlist (@Query ("sort") String sort);

3. Set the path parameter in the GET tag:

    @GET ("Group/{id}/users")    callint groupId);


4. Incoming parameter list:

    @GET ("Group/{id}/users")    callint groupId, @QueryMap map<string, string> options);


5, POST method request:

    @POST ("Users/new")    call <User> createUser (@Body user user);

Three, Retrofit principle:

Retrofit uses annotations to describe a network request, abstracting a network request into an interface, and then dynamically "translates" the interface into a network request using a Java dynamic proxy, and finally calls Okhttp to execute the request.

The dynamic proxy in retrofit is mainly embodied in the following line of code:

Retrofitservice service = Retrofit.create (retrofitservice.  Class);

The source code for the Create () method is as follows:

/**Create A implementation of the API defined by the {@codeService} interface. */ Public<T> T Create (FinalClass<t>service)    {utils.validateserviceinterface (service); if(validateeagerly) {eagerlyvalidatemethods (service); }    return(T) Proxy.newproxyinstance (Service.getclassloader (),NewClass<?>[] {service},NewInvocationhandler () {Private FinalPlatform Platform =Platform.get ();  PublicObject Invoke (Object proxy, Method method, Object ... args)throwsThrowable {//If The method is a method from Object then defer to normal invocation.            if(Method.getdeclaringclass () = = Object.class) {                returnMethod.invoke ( This, args); }            if(Platform.isdefaultmethod (method)) {returnPlatform.invokedefaultmethod (method, service, proxy, args); } Servicemethod Servicemethod=Loadservicemethod (method); Okhttpcall Okhttpcall=NewOkhttpcall<>(Servicemethod, args); returnserviceMethod.callAdapter.adapt (Okhttpcall); }    });}

As you can see, the so-called dynamic agent is a possibility for programmers to insert a piece of code that you want to execute before performing an operation, such as opening a class. For example, before you perform an operation, you determine whether the user is logged in or not.

When the outside world (Activity) opens the interface through the Create () method and invokes the method in it, the underlying is called the Invode () method in the above code. This method is obtained through the Java reflection mechanism to the interface of the Getinfodata () method, using this method as a parameter to create a Servicemethod object, and finally use the Okhttp API calls for network access.

To summarize: Retrofit uses annotations to encapsulate a network request into an interface, and then uses the dynamic proxy method to find the method in the interface through the reflection mechanism in the injected code, encapsulating the network access in the Okhttp. Finally, the Enqueue () or execute () operation is performed on the call object obtained by the network access, and the data obtained by the network is processed in the callback method.

The above is the working principle of retrofit.

Use of the "Android-frame" retrofit

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.