Retrofit of positioning
Retrofit is not built as a network request repository, but as a network request adaptation layer. For example, if the network request library is JDBC, MyBatis is Retrofit. Retrofit2 uses OkHttp as its network request library by default underneath, which itself encapsulates the general operations of the network request process, such as parameter construction, data parsing, and thread switching. Retrofit is Restful in its simplicity, defining each network request as a method of the Java interface. The definition path can be provided by method annotations, headers and request parameters can be provided by method parameters, and returning a Retrofit Call object, This Call connection is similar to OkHttp calls. Network requests can be executed synchronously and asynchronously in execute and enqueue modes.
Retrofit Demo
Again, use the previous OkHttp3 demo, but extract the style definition as a public function, exposing only network requests.
package com.benson.android.network import android.content.Context import android.graphics.Color import android.view.Gravity import android.view.ViewGroup import android.widget.* fun initView(context: Context, search: (TextView, String) -> Unit): ViewGroup { val content = LinearLayout(context) content.orientation = LinearLayout.VERTICAL val searchBar = LinearLayout(context) searchBar.orientation = LinearLayout.HORIZONTAL searchBar.gravity = Gravity.CENTER val input = EditText(Context) input.textSize = DisplayUtil. Sp2px (Context, 10.0f) * 1.0f Searchbar. addView(Input, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 7.0f)) val searchBtn = Button(context) searchbtn. text = "search" searchbtn. textSize = displayUtil.sp2px (context, 10.0 F) * 1.0 F searchBar. AddView (searchBtn LinearLayout. LayoutParams (0, LinearLayout. LayoutParams. MATCH_PARENT, 2.0 F)) content. addView (searchBar, LinearLayout. LayoutParams (LinearLayout. LayoutParams. MATCH_PARENT, 0, 1.0 F)) val result = TextView (context) result. SetBackgroundColor (Color. BLACK) result. SetTextColor (Color. WHITE) result.textSize = DisplayUtil.sp2px(context, 15.0f) * 1.0f val scrollView = scrollView (context) scrollView.addView(result) content.addView(scrollView, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, (10.0 F)) searchBtn. SetOnClickListener {search result, the input. The text. The toString ())} return content}Copy the code
The basic configuration of OkHttp is used here, and asynchronous callbacks are used
package com.benson.android.network import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import okhttp3.OkHttpClient import retrofit2.* import retrofit2.converter.gson.GsonConverterFactory import retrofit2.http.GET import retrofit2.http.Path import java.lang.StringBuilder import java.util.concurrent.TimeUnit class Retrofit2DemoActivity: AppCompatActivity() { companion object { const val BASE_URL = "https://api.github.com/users/" interface UserResource { @GET("{user}") fun getUser(@Path("user") user: String): Call < User >}} val client by lazy {OkHttpClient. Builder (). RetryOnConnectionFailure (true) / / connection timeout retry connectTimeout (2 l, Timeunit.minutes) // 2s connection timeout. ReadTimeout (2L, timeunit.minutes) // 2s readTimeout. WriteTimeout (2L, writeTimeout) Timeunit.minutes) // 2s write timeout.build()} val retrofit by lazy {retrofit.builder ().baseurl (BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(client) .build() } val userResource by lazy { retrofit.create(UserResource::class.java) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(initView(this) { result, user -> userResource.getUser(user).enqueue(object: Callback<User> { override fun onFailure(call: Call<User>, t: Throwable) { result.text = "query error with user=$user\n${t.message}" } override fun onResponse(call: Call<User>, response: Response<User>) { result.text = StringBuilder("code=${response.code()}").append("\n") .append("message=").append(response.message()).append("\n") .append("body=").append(response.body()).toString() } }) }) }}Copy the code
The entity class is automatically generated from json to Javabean
The entire request process is simply described as using Retrofit.Builder to construct a Retrofit object, and using Retrofit to create a Restful interface object that we need to use. We don’t need to implement the interface ourselves, Retrofit automatically implements it for us, passing the parameters to the interface’s methods when requesting it. Such a network request is like calling a normal Java method, and the callback for an asynchronous request is Retrofit automatically switching us to the main thread.
Retrofit source code parsing
The build method is called Retrofit, which uses the Builder, passes in a set of build parameters, and returns a Retrofit object. The build method ends with a new Retrofit object, Pass the callFactory, baseUrl, converterFactories, callAdapterFactories, callbackExecutor, and Validateincorporated objects into Retrofit’s constructor.
- CallFactory: Represents the network requester, the interface that actually performs the network request
- BaseUrl: URL prefix for network requests. Retrofit considers the same Retrofit to represent a series of requests under the same domain name
- ConverterFactories: Type Converter factories that convert Java objects into Network request parameters and response results into Java objects.
- CallAdapterFactories: Call adapter factories that produce Calladapters that convert the underlying call type returned to the return type defined by the request interface.
- CallbackExecutor, an executor for asynchronous callbacks, uses MainThreadExecutor by default and executes runnable using Handler(looper.getMainLooper ()).post.
- Validategbit/s: Whether methods defined in RetrofitInterface are cached in advance into Retrofit
Retrofit objects use the create method to pass in the Class of an interface to create a proxy object for that interface. Retrofit uses Java proxies by default to create Proxy objects. The implementation of a Proxy object is to create a ServiceMethod object and call its adapt method, which is the corresponding Adapt method of the invoked ServiceMethod when the method requesting the interface is called. For example, if a method defined in RetrofitInterface is cached ahead of time, then the create method uses this method. If the value is true, All servicemethods are created and cached ahead of time, and the ServiceMethod can be retrieved from the cache when it is actually called by loadServiceMethod. The adapt method of ServiceMethod directly calls the CallAdapter. adapt. The callAdapter of ServiceMethod is created using the createCallAdapter method during its build. The createCallAdapter method of ServiceMethod gets the annotation and return type of the request interface method and is created using the callAdapter method of the RetroFIT object. In Retrofit objects, the callAdapter directly calls the nextCallAdapter method, using callAdapterFactories to create the callAdapter object. CallAdapterFactories here is to build to create Retrofit object to come in, if not, will also add into the platform. DefaultCallAdapterFactory. DefaultCallAdapterFactory method for incoming parameters callbackExecutor sentenced to empty, of course, the callbackExecutor here is not empty, because the default is in the main thread of the callback, So use ExecutorCallAdapterFactory callAdapterFactory default. While the get method of ExecutorCallAdapterFactory created a CallAdapter object, its ExecutorCallbackCall adapt method is to return to create objects, The ExecutorCallback object is the real object of a Call that we return on the outside using userResource.getUser(user). So the real request process falls in the ExecutorCallAdapterFactory the enqueue method, the enqueue method only calls the delegate the enqueue method, OnReponse calls the onResponse of the incoming callback object, onFailture calls the onFailure of the callback, and the callback is posted to the callbackExecutor. The delegate object is the OkHttpCall object that was passed in during ExecutorCallback creation. In the enQueue implementation, the OkHttpCall is used to Call its enqueue method, and in the callback of the EnQueue method, Call the corresponding ExecutorCallback callback, which completes OkHttp’s request proxy for Retrofit’s requests. If you want to implement other network request underlying libraries to implement Retrofit’s requests, you can also emulate OkHttp’s proxy implementation for Retrofit. Because OkHttp does not come with javabean parsing, Retrofit is needed to adapt OkHttp request results to javabean parsing. In OkHttpCall’s response callback, parseResponse is used. It calls Servicemethod. toResponse to create a Javabean object. ServiceMethod’s toResponse method calls responseConverter convert directly. Remember that when we created Retrofit convert was passed GsonConverterFactory. So here using the converter of the real object is returned GsonConverterFactory responseBodyBodyConverter GsonResponseBodyConverter object. The convert method is a Javabean object constructed by calling the Read method using the JsonReader object directly.
conclusion
Retrofit is not a network request library, but a Network request adaptation library. It is a library that ADAPTS network requests to application development, making calling network requests as easy as calling a normal Java method, and following a restful interface style. Retrofit defines web requests using Java interfaces, whose methods represent the request parameters, and the additional information of the request is represented by annotation information. This Java interface does not need to be developed and implemented by us, but is implemented by The Dynamic Proxy framework of Java inside Retrfit. In the invoke method, the constructed ServiceMethod method is used to complete the construction of Call. The Call object’s actual execute execute and enqueue methods are proxied to the real network request library. For converting network request parameters or network request results to Javabeans, Retrofit provides the Converter
interface, which has only one method convert, which converts a given type F to a defined type T. Retrofit is becoming more and more popular, and people are more interested in Retrofit than OkHttp, because the focus is on application development architecture, and in application development, the development pattern is often more important than the underlying implementation, which is why the Java language is more popular with C/C++. Java is full of C/C++, so use C/C++ development is not good? But the problem is that Java development makes it easier for developers to focus on the development pattern rather than the underlying implementation, just as Retrofit allows developers to make network requests just like normal Java methods, regardless of what the network request actually does.