In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces "how to use the Retrofit source code in Android". In daily operation, I believe many people have doubts about how to use the Retrofit source code in Android. Xiaobian consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the doubt of "how to use the Retrofit source code in Android". Next, please follow the editor to study!
Basic usage
Retrofit turns HTTP API into an interface for Java. Here is an example of Retrofit's official website:
Public interface GitHubService {@ GET ("users/ {user} / repos") Call listRepos (@ Path ("user") String user);}
There is a method listRepos in the GithubService interface, which is annotated in the way @ GET, which indicates that this is a GET request. The users/ {user} / repos in the following parentheses is the path of the request, where {user} indicates that this part is dynamic, its value is passed by the parameter of the method, and the parameter @ Path ("user") String user of this method is used to replace {user}. Also note that the return value of this method is Call. You can see that Retrofit uses annotations to describe the parameters related to a network request.
The above is the beginning, and the following is to make this network request:
Retrofit retrofit = new Retrofit.Builder () .baseUrl ("https://api.github.com/") .addConverterFactory (GsonConverterFactory.create ()) .build (); GitHubService service = retrofit.create (GitHubService.class); Call repos = service.listRepos (" octocat ")) Repos.enqueue (new Callback () {@ Override public void onResponse (Call call, Response response) {} @ Override public void onFailure (Call call, Throwable t) {}})
As you can see, first you build a Retrofit object with the baseUrl parameter passed in, and the baseUrl and the path following the GET method above are combined to form a complete url. In addition to baseUrl, there is a converterFactory that converts the returned http response into a Java object, corresponding to the List > in the method's return value Call, where Repo is a custom class. With the Retrofit object, you call its create method to create an instance of GitHubService, and then you can call the method of that instance to request the network. Call the listRepo method to get a Call object, and then you can use enqueue or execute to execute the initiating request, enqueue is executed asynchronously and execute is executed synchronously.
This is the basic use of Retrofit, and other details can be found on the official website.
Source code analysis
When I came into contact with Retrofit, I thought it was magical, and its usage was different from that of ordinary web requests. Let's take a look at how the source code of Retrofit is implemented.
The creation of Retrofit
As you can see from the way Retrofit is created, the Builder mode is used. There are several key variables in Retrofit:
/ / used to cache the parsed method private final Map serviceMethodCache = new LinkedHashMap (); / / the factory of the OKHttp of the request network. The default is OkHttpClient private final okhttp3.Call.Factory callFactory; / / baseurl private final HttpUrl baseUrl; / / the collection of response converters obtained by the request network will join BuiltInConverters private final List converterFactories; / / convert the Call object to other types of private final List adapterFactories by default. / / used to execute callback Android. The default is MainThreadExecutor private final Executor callbackExecutor; / / whether the method private final boolean validateEagerly in the interface needs to be parsed immediately.
Take another look at the builder method of the inner class Builder in Retrofit:
Public Retrofit build () {if (baseUrl = = null) {throw new IllegalStateException ("Base URL required.");} okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory = = null) {/ / create an OkHttpClient callFactory = new OkHttpClient () by default;} Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor = = null) {/ / Android returns MainThreadExecutor callbackExecutor = platform.defaultCallbackExecutor () } / / Make a defensive copy of the adapters and add the default Call adapter. List adapterFactories = new ArrayList (this.adapterFactories); adapterFactories.add (platform.defaultCallAdapterFactory (callbackExecutor)); / / Make a defensive copy of the converters. List converterFactories = new ArrayList (this.converterFactories); return new Retrofit (callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly);}
When creating a Retrofit, if no OkHttpClient is specified, a default is created. If callbackExecutor is not specified, it will return to the platform default, which is MainThreadExecutor in Android, and use this to build a CallAdapter to join adapterFactories.
Create method
Once you have the Retrofit object, you can create an instance of the network request interface class through the create method, as follows:
Public T create (final Class service) {Utils.validateServiceInterface (service); if (validateEagerly) {/ / advance parsing method eagerlyValidateMethods (service);} return (T) Proxy.newProxyInstance (service.getClassLoader (), new Class [] {service}, new InvocationHandler () {private final Platform platform = Platform.get (); @ Override public Object invoke (Object proxy, Method method, Object...) Args) throws Throwable {/ / If the method is a method from Object then defer to normal invocation. If it is a method in Object, call if (method.getDeclaringClass () = = Object.class) {return method.invoke (this, args);} / / for compatibility with Java8 platform, if (platform.isDefaultMethod (method)) {return platform.invokeDefaultMethod (method, service, proxy, args) will not be executed in Android } / / the following is the key point, parsing method ServiceMethod serviceMethod = loadServiceMethod (method); OkHttpCall okHttpCall = new OkHttpCall (serviceMethod, args); return serviceMethod.callAdapter.adapt (okHttpCall);}})
The create method accepts a Class object, the interface we wrote, that contains the method that requests the network identified by the annotation. Notice the return statement section, where the Proxy.newProxyInstance method is called, which is important because the dynamic proxy pattern is used. To put it simply, Proxy.newProxyInstance generates an instance A, the proxy class, based on the incoming Class object. Whenever this proxy class An executes a method, it always calls the invoke method of InvocationHandler (the third parameter in Proxy.newProxyInstance), in which you can perform some operations (in this case, the annotation parameters of the parsing method, etc.), using this method to actually execute the network request in the interface we wrote.
Method parsing and type conversion
Let's take a look at a few lines of the parsing network request method in invoke. First, ServiceMethod serviceMethod = loadServiceMethod (method);, where the loadServiceMethod code is as follows:
ServiceMethod loadServiceMethod (Method method) {ServiceMethod result; synchronized (serviceMethodCache) {result = serviceMethodCache.get (method); if (result = = null) {result = new ServiceMethod.Builder (this, method). Build (); serviceMethodCache.put (method, result);}} return result;}
As you can see, it is first found in the cache, and it is not created in the cache. Here the ServiceMethod object is created. ServiceMethod is used to convert a call to an interface method into a HTTP request. In fact, in ServiceMethod, it parses the comments, parameters, and so on of methods in the interface, and it also has a toRequest method that is used to generate a Request object. This Request object is the Request in OkHttp, which represents a network request (Retrofit actually leaves the operation that actually requests the network to OkHttp to execute). Here is part of the code to create the ServiceMethod:
Public ServiceMethod build () {/ / get callAdapter callAdapter = createCallAdapter (); responseType = callAdapter.responseType (); if (responseType = = Response.class | | responseType = = okhttp3.Response.class) {throw methodError ("'" + Utils.getRawType (responseType). GetName () + "'is not a valid response body type. Did you mean ResponseBody? ");} / / get responseConverter responseConverter = createResponseConverter (); for (Annotation annotation: methodAnnotations) {/ / parse the annotation parseMethodAnnotation (annotation); / / omit some code.}}
After you get the ServiceMethod object, you pass it to the OkHttpCall object along with the relevant parameters of the method call, which is this line of code: OkHttpCall okHttpCall = new OkHttpCall (serviceMethod, args);. Here's how OkHttpCall,OkHttpCall inherits from the Call interface. Call is the basic interface of Retrofit, which represents sending network request and response calls. It includes the following interface methods:
Response execute () throws IOException; / / synchronous execution request
Void enqueue (Callback callback); / / execute the request asynchronously. Callback is used for callback.
Boolean isExecuted (); / / whether it has been executed
Void cancel (); / / cancel the request
Boolean isCanceled (); / / whether canceled or not
Call clone (); / / Clone a request
Request request (); / / get the original request
OkHttpCall is an implementation class of Call, which encapsulates the native Call in OkHttp, and implements methods such as execute and enqueue in this class, which actually calls the corresponding methods of native Call in OkHttp.
Next, pass OkHttpCall to the serviceMethod.callAdapter object. What is the callAdapter here? In the above code to create the ServiceMethod, there is a line of code: callAdapter = createCallAdapter (). Here you create the calladapter. Inside this code, you look for the corresponding CallAdapter based on the return type of the method and the annotation. Where can you find it? Look in the adapterFactories collection of the Retrofit object. When we create the Retrofit, we can call addCallAdapter to add the CallAdapter to the adapterFactories. In the previous basic usage, we didn't add any CallAdapter, but an ExecutorCallAdapterFactory is added by default in adapterFactories, and the CallAdapter object is obtained by calling its get method.
So what does CallAdapter do? The adapt method is called above to convert one Call to another. For example, when Retrofit is used in conjunction with RxJava, the method in the interface can return Observable, which is equivalent to the adapter pattern. By default, you get a Call object, which is ExecutorCallbackCall, with the following code:
Public CallAdapter > () {@ Override public Type responseType () {return responseType;} @ Override public Call adapt (Call call) {return new ExecutorCallbackCall (callbackExecutor, call);}};}
This ExecutorCallbackCall accepts a callbackExecutor (MainThreadExecutor is the default in Android to pass the returned data back to the main thread) and a call, which is OkhttpCall. Take a look at some of the ExecutorCallbackCall code:
Static final class ExecutorCallbackCall implements Call {final Executor callbackExecutor; final Call delegate; ExecutorCallbackCall (Executor callbackExecutor, Call delegate) {this.callbackExecutor = callbackExecutor; this.delegate = delegate;} @ Override public void enqueue (final Callback callback) {if (callback = = null) throw new NullPointerException ("callback = = null") Delegate.enqueue (new Callback () {@ Override public void onResponse (Call call, final Response response) {callbackExecutor.execute (new Runnable () {@ Override public void run () {if (delegate.isCanceled ()) {/ / Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation. Callback.onFailure (ExecutorCallbackCall.this, new IOException ("Canceled"));} else {callback.onResponse (ExecutorCallbackCall.this, response);});} @ Override public void onFailure (Call call, final Throwable t) {callbackExecutor.execute (new Runnable () {@ Override public void run () {callback.onFailure (ExecutorCallbackCall.this, t) });});}
In the enqueue method, OkHttpCall's enqueue is called, so this is equivalent to static proxy mode. The enqueue in OkHttpCall actually calls the enqueue in the native OkHttp, and the network request is actually issued here. Part of the code is as follows:
@ Override public void enqueue (final Callback callback) {if (callback = = null) throw new NullPointerException ("callback = = null"); / / call okhttp3.Call call; Throwable failure; synchronized (this) {if (executed) throw new IllegalStateException ("Already executed.") that actually requests the network; executed = true; / / omits some of the code. Call = rawCall; / / enqueue asynchronously execute call.enqueue (new okhttp3.Callback () {@ Override public void onResponse (okhttp3.Call call, okhttp3.Response rawResponse) throws IOException {Response response; try {/ / parsing data will use conveterFactory to convert response to the corresponding Java type response = parseResponse (rawResponse);} catch (Throwable e) {callFailure (e) Return;} callSuccess (response);} @ Override public void onFailure (okhttp3.Call call, IOException e) {try {callback.onFailure (OkHttpCall.this, e);} catch (Throwable t) {t.printStackTrace () } private void callFailure (Throwable e) {try {callback.onFailure (OkHttpCall.this, e);} catch (Throwable t) {t.printStackTrace ();}} private void callSuccess (Response response) {try {callback.onResponse (OkHttpCall.this, response);} catch (Throwable t) {t.printStackTrace ();}});}
After OkHttp obtains the data, it parses the data and calls back the method of callback response, and a network request is completed.
At this point, the study on "how to use the Retrofit source code in Android" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.