最近学习了Kotlin,感受就是好处太多了 欲罢不能,这其中协程这个特点处理异步非常不错,于是花了很长时间结合Retrofit封装了网络请求,感觉非常简洁好用。先看下调用方式

准备工作:Retrofit的初始化 常规写法

引入第三方

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"

接口定义

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

使用顶层函数和懒加载初始化ApiInterface 

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, TimeUnit.SECONDS) //设置写的超时时间
        .connectTimeout(30, TimeUnit.SECONDS)
    if (BuildConfig.DEBUG) {
        val httpLoggingInterceptor = HttpLoggingInterceptor()
        builder.addInterceptor(httpLoggingInterceptor.apply {
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        })
    }
    return builder.build()
}

 

一:最简单的调用

class MainVm : BaseViewModel() {
    val responseText=ObservableField<String>("11111");

    /**
     * 请求网络
     */
    fun requestData(){
        viewModelScope.launch {
            request {
                getListProject();
            }.next {
                Log.e("data===>","data=====>${this.data}")
                responseText.set(this.data.toString())
            }
        }
    }
}

:所有请求都是再ViewModel中进行的,因为我使用了viewModelScope可以防止内存泄漏。调用起来是不是特别简洁

这里说明一下 viewModelScope.launch就是开启一个协程,不用多说,然后里面调用了request方法请求网络,这个方法我封装再BaseViewModel中。getListProject方法就是定义再ApiInterface 的网络接口,后面next方法就是请求成功的处理,之所以用next名称是因为之前用了很长时间的Rxjava。调用的时候默认开启请求的对话框的。

二:关闭对话框的请求

class MainVm : BaseViewModel() {
    val responseText=ObservableField<String>("11111");

    /**
     * 请求网络
     */
    fun requestData(){
        viewModelScope.launch {
            request(false) {
                getListProject();
            }.next {
                Log.e("data===>","data=====>${this.data}")
                responseText.set(this.data.toString())
            }
        }
    }
}

request传入false即可,最后是不是还得加个获取异常。

三:异常获取

class MainVm : BaseViewModel() {
    val responseText=ObservableField<String>("11111");

    /**
     * 请求网络
     */
    fun requestData(){
        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->{
                        
                    }
                }
            }
        }
    }
}

是不是很简单后面加上catchException 方法就获取到了所有的异常,当然request方法里面已经对异常统一处理了,不过demo里面统一处理为简单的土司

 

感觉这样封装调用起来真方便,这还得益于kotlin的kotlin lambda表达式 还有带有接收者的函数 就是方便方便方便方便

 

最后附上demo地址:https://github.com/wangxiongtao/kotlinBaseDemo,如果又好的修改建议,评论区告诉我吧

 

 

 

 

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐