Retrofit is introduced

Retrofit is Square’s open source web request framework based on OkHttp (which is also his company’s) wrapper. Most of the web requests are still done by OkHttp. Retrofit just wraps OkHttp and makes it easier to use. Retrofit is one of those must-ask interview questions, so not only should we know how to use it, but we should also have a general understanding of how it works.

From the perspective of using this article, I hope you can communicate with me in the comments section. I will improve in time and make progress together. The demo in this article can be downloaded from Github.

Retrofit advantages

Much of Retrofit’s configuration is annotated, making it simple to configure and easy to use; Supports multiple return types including RxJava and coroutines, and can be configured with different parsers for data parsing, such as Json, XML, etc

The use of the Retrofit

The following code is all written in Kotlin, which is the trend now.

1. Introduce dependencies

Github address: github.com/square/retr…

Implementation 'com. Squareup. Retrofit2: retrofit: 2.9.0' / / support Gson parsing json data implementation 'com. Squareup. Retrofit2: converter - gson: 2.9.0' / / support RxJava return type implementation "Com. Squareup. Retrofit2: adapter - rxjava2:2.9.0" implementation "IO. Reactivex. Rxjava2: rxandroid: 2.0.2" / / supports coroutines, Retrofit2.6.0 and above does not need to be introduced,Retrofit has built-in support for //implementation 'com. Jakewharton. Retrofit: retrofit2 - kotlin coroutines -- adapter: 0.9.2'Copy the code

2. Add network permissions

<uses-permission android:name="android.permission.INTERNET"/>
Copy the code

2. Write Retrofit helper classes

Start by defining a RetrofitHelper helper class and writing a Retrofit singleton. Retrofit already maintains thread pools internally for network requests, so you don’t need to create multiple

Note: BASE_URL must end with a “/”

Private const val BASE_URL = "https://www.baidu.com" private var retrofit: Retrofit? = null private var retrofitBuilder: If (retrofitBuilder == null) {val client = okHttpClient.builder () .connectTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .writeTimeout(20, Timeunit.seconds).build() retrofitBuilder = retrofit.Builder ().baseurl (BASE_URL) // Support Json data parsing AddConverterFactory (GsonConverterFactory. The create ()) / / support RxJava return type .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .client(client) } retrofit = retrofitBuilder!! .build() } fun getRetrofit():Retrofit{ if (retrofit == null) { throw IllegalAccessException("Retrofit is not initialized!" ) } return retrofit!! }}Copy the code

And then initialize it in Application

class App:Application() {

    override fun onCreate() {
        super.onCreate()
        RetrofitHelper.init()
    }
}
Copy the code

Specify the Application in the Manifest file

<application
    android:name=".App"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:networkSecurityConfig="@xml/network_security_config"
    android:theme="@style/Theme.RetrofitDemo">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
Copy the code

Android P system limits the clear text traffic network request solution has two ways 1. Change all HTTP requests to HTTPS requests. 2. In the XML directory () of res, create a file named network_security_config.xml

<? The XML version = "1.0" encoding = "utf-8"? > <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>Copy the code

4. Define ApiService

Let’s try it out first with a simple GET request, which is free to request weather conditions

interface Api {
    @GET("http://www.weather.com.cn/data/sk/{cityCode}.html")
    fun getWeather(@Path("cityCode")code:String):Observable<WeatherInfo>
}
Copy the code

Defines the return type, the data class type used for printing

data class WeatherInfo( var weatherinfo:Info? =null) { data class Info( var city:String? , var cityid:String? , var temp:String? , var WD:String? , var WS:String? , var SD:String? , var AP:String? , var njd:String? , var WSE:String? , var time:String?) }Copy the code

The value of the GET annotation is the request address. The complete request address is baseUrl+value. If value is the complete address, value will be used as the request address. BaseUrl = “www.weather.com.cn/”, then GET(“data/sk/{cityCode}.html”) @path is the url parameter, used instead.

5. Implement interface methods

5.1RxJava method implementation

class RetrofitViewModel:ViewModel() { private val disposables:CompositeDisposable by lazy { CompositeDisposable() } fun addDisposable(d:Disposable){ disposables.add(d) } val weatherLiveData = MutableLiveData<WeatherInfo>() fun getWeather(){  RetrofitHelper.getRetrofit().create(Api::class.java).getWeather("101010100") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object :Observer<WeatherInfo>{ override fun onComplete() {} override fun onSubscribe(d: Disposable) { addDisposable(d) } override fun onNext(t: WeatherInfo) { weatherLiveData.value = t } override fun onError(e: Throwable) { } }) } override fun onCleared() { super.onCleared() disposables.clear() } }Copy the code

Call the getWeather method of the Service object with a Retrofit singleton, specify the thread of the upstream and downstream events, and create an observer object to listen on. The onNext method returns the result and calls back to the Activity. The data callback is LiveData

class MainActivity : AppCompatActivity() { private val viewModel by viewModels<RetrofitViewModel>() private var btnWeather: Button? = null private var tvWeather: TextView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewModel.weatherLiveData.observe(this, Observer { tvWeather? .text = it.toString()) }) btnWeather = findViewById<Button>(R.id.btnWeather) tvWeather = findViewById(R.id.tvWeather) btnWeather? .setOnClickListener { viewModel.getWeather() } } }Copy the code

In the Activity

1. Create a ViewModel object

2. Register LiveData callbacks

3. Get the weather

As shown in the figure below

Github address: github.com/ZhiLiangT/R…