Recently, I learned Kotlin and felt that there are too many benefits to stop. The feature of coroutines is very good for handling asynchrony, so I spent a long time combining Retrofit to encapsulate network requests, which felt very simple and easy to use.

Preparation: Initial general writing of Retrofit

Bring in third Parties

Implementation "androidx. Lifecycle: lifecycle - extensions: 2.2.0" implementation "Androidx. Lifecycle: lifecycle - viewmodel - KTX: 2.2.0" implementation "com. Squareup. Retrofit2: retrofit: 2.9.0" implementation "Com. Squareup. Okhttp3: logging - interceptor: 4.2.0" implementation "com. Squareup. Retrofit2: converter - gson: 2.9.0"Copy the code

BaseResponse

class BaseResponse<T> {
    val data: T? = null;
    val errorCode: Int? = null;
    val errorMsg: String? = null;
    var exception: Exception? = null;
}
Copy the code

Api interface

interface ApiInterface {
    @GET("/article/listproject/0/json")
    suspend fun getListProject(): BaseResponse<ListProjectBean?>
}
Copy the code

Initialize the

Initialize the ApiInterface with top-level functions and lazy loading

val Api: ApiInterface by lazy { Retrofit.Builder() .baseUrl("https://www.wanandroid.com") .addConverterFactory(GsonConverterFactory.create()) .client(getOkHttpClient()) .build().create(ApiInterface::class.java)  } private fun getOkHttpClient(): OkHttpClient { val builder: Okhttpclient.builder = okHttpClient.builder ().readTimeout(30, timeunit.seconds).writeTimeout(30, writeTimeout) Timeunit.seconds) // Set the write timeout time. ConnectTimeout (30, TimeUnit.SECONDS) if (BuildConfig.DEBUG) { val httpLoggingInterceptor = HttpLoggingInterceptor() builder.addInterceptor(httpLoggingInterceptor.apply { httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY }) } return builder.build() }Copy the code

Began to call

One: the simplest call

class MainVm : BaseViewModel() { val responseText=ObservableField<String>("11111"); Funrequestdata (){viewModelscope.launch {request {getListProject(); }.next { Log.e("data===>","data=====>${this.data}") responseText.set(this.data.toString()) } } } }Copy the code

All requests are made in the ViewModel because I use the viewModelScope to prevent memory leaks. Is it particularly neat to call

Viewmodelscope. launch is a coroutine that, needless to say, calls the Request method to request the network, which I encapsulate in BaseViewModel. The getListProject method is the network interface that defines the ApiInterface, followed by the next method that handles the success of the request (which is modeled after Kotlin’s Apply method). The next method is named because Rxjava has been used before. The request dialog box is then opened by default.

Two: close the dialog box request

class MainVm : BaseViewModel() { val responseText=ObservableField<String>("11111"); Funrequestdata (){viewModelscope.launch {request(false) {getListProject(); }.next { Log.e("data===>","data=====>${this.data}") responseText.set(this.data.toString()) } } } }Copy the code

Request: false; request: false;

Three: exception acquisition

class MainVm : BaseViewModel() { val responseText=ObservableField<String>("11111"); Funrequestdata (){viewModelscope.launch {request(false) {getListProject(); }.next { Log.e("data===>","data=====>${this.data}") responseText.set(this.data.toString()) }.catchException { when(this){ is ApiException->{ } is IOException->{ } else->{ } } } } } }Copy the code

Catch all the exceptions in the catchException () request () method

This feels like a handy way to wrap calls, thanks to kotlin’s lambda expressions and functions with receivers

Github address:

Github.com/wangxiongta…

Comments and suggestions are welcome

See this article for flow encapsulation using Kotlin

Juejin. Cn/post / 696355…