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…