Kotlin + Retrofit + RxJava简单封装使用详解
本文介绍了Kotlin+Retrofit+RxJava简单封装使用详解,分享给大家,具体如下:
实例化Retrofit
objectRetrofitUtil{
valCONNECT_TIME_OUT=30//连接超时时长x秒
valREAD_TIME_OUT=30//读数据超时时长x秒
valWRITE_TIME_OUT=30//写数据接超时时长x秒
valretrofit:Retrofitbylazy{
Log.d("RetrofitUtil","retrofitinitlazy")
Retrofit.Builder()
.baseUrl("http://gank.io/api/")//本文以GitHubAPI为例
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(getOkHttpClient())
.build()
}
privatefungetOkHttpClient():OkHttpClient{
valbuilder=OkHttpClient.Builder()
builder.connectTimeout(CONNECT_TIME_OUT.toLong(),TimeUnit.SECONDS)
.writeTimeout(WRITE_TIME_OUT.toLong(),TimeUnit.SECONDS)
.readTimeout(READ_TIME_OUT.toLong(),TimeUnit.SECONDS)
if(BuildConfig.DEBUG){
builder.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
}else{
builder.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.NONE))
}
//设置请求头
builder.addInterceptor{chain->
valtime=(System.currentTimeMillis()/1000).toString()+""
valrequestBuilder=chain.request().newBuilder()
requestBuilder.addHeader("time",time)
chain.proceed(requestBuilder.build())
}
returnbuilder.build()
}
}
返回数据封装
classResponse{ varerror:Boolean=false varresults:T?=null }
demo中用了gank.io的开发api,之前一般项目的返回格式是code+message+T的格式。
api接口错误/异常统一处理类
classApiException:Exception{
varcode:Int=0//错误码
varmsg:String?=null//错误信息
constructor(throwable:Throwable,code:Int):super(throwable){
this.code=code
}
constructor(code:Int,msg:String){
this.code=code
this.msg=msg
}
}
定义ExceptionFunction处理onErrorResumeNext:
classExceptionFunction:Function >{ overridefunapply(@NonNullthrowable:Throwable):Observable { Log.e("ExceptionFunction",throwable.message) returnObservable.error(ExceptionEngine().handleException(throwable)) } } /** *错误/异常处理工具 */ classExceptionEngine{ valUN_KNOWN_ERROR=1000//未知错误 valANALYTIC_SERVER_DATA_ERROR=1001//解析(服务器)数据错误 valCONNECT_ERROR=1002//网络连接错误 valTIME_OUT_ERROR=1003//网络连接超时 funhandleException(e:Throwable):ApiException{ valex:ApiException if(eisApiException){//服务器返回的错误 returne }elseif(eisHttpException){//HTTP错误 ex=ApiException(e,e.code()) ex.msg="网络错误:"+ex.code returnex }elseif(eisJsonParseException ||eisJSONException ||eisParseException||eisMalformedJsonException){//解析数据错误 ex=ApiException(e,ANALYTIC_SERVER_DATA_ERROR) ex.msg="解析错误" returnex }elseif(eisConnectException){//连接网络错误 ex=ApiException(e,CONNECT_ERROR) ex.msg="连接失败" returnex }elseif(eisSocketTimeoutException){//网络超时 ex=ApiException(e,TIME_OUT_ERROR) ex.msg="网络超时" returnex }else{//未知错误 ex=ApiException(e,UN_KNOWN_ERROR) ex.msg=e.message returnex } } }
封装请求处理
objectRx{
/**
*Rxlifecycle绑定生命周期
*/
funget(observable:Observable>,lifecycleProvider:LifecycleProvider):Observable{
//请求绑定生命周期,防止内存泄漏,同时返回回调之后页面已销毁造成的空指针错误
if(lifecycleProviderisRxAppCompatActivity){
valrxAppCompatActivity=lifecycleProviderasRxAppCompatActivity
observable.compose(rxAppCompatActivity.bindUntilEvent(ActivityEvent.DESTROY))
}elseif(lifecycleProviderisRxFragment){
valrxFragment=lifecycleProviderasRxFragment
observable.compose(rxFragment.bindUntilEvent(FragmentEvent.DESTROY))
}
returnobservable
.compose(HandleResult())
.onErrorResumeNext(ExceptionFunction())
}
/**
*部分后台请求
*/
funget(observable:Observable>):Observable{
returnobservable
.compose(HandleResult())
.onErrorResumeNext(ExceptionFunction())
}
privateclassHandleResult:ObservableTransformer,T>{
overridefunapply(upstream:Observable>):ObservableSource{
returnupstream.flatMap{response->createResult(response)}
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
}
privatefuncreateResult(response:Response):Observable{
returnObservable.create({subscriber->
if(response.error)
throwApiException(-1,"服务器异常")//一般来说,自己的服务器异常会返回相应的code和message
else
response.results?.let{
subscriber.onNext(response.results!!)
}?:subscriber.onComplete()
})
}
}
定义HttpObserver统一处理返回
abstractclassHttpObserver:Observer { /** *标记是否为特殊情况 */ privatevarresultNull:Boolean=true overridefunonComplete(){ //特殊情况:当请求成功,但T==null时会跳过onNext,仍需当成功处理 if(resultNull) onSuccess(null) } overridefunonSubscribe(d:Disposable){ //可在此处加上dialog } overridefunonError(e:Throwable){ if(eisApiException){ onError(e.code,e.msg) }else{ onError(0,e.message) } } overridefunonNext(t:T){ resultNull=false onSuccess(t) } abstractfunonSuccess(t:T?) /** *统一处理失败,比如登录失效等 * *@paramcode *@parammsg */ openfunonError(code:Int,msg:String?){ } }
Api
classResult{
var_id:String?=null
varcreatedAt:String?=null
vardesc:String?=null
varpublishedAt:String?=null
varsource:String?=null
vartype:String?=null
varurl:String=""
varisUsed:Boolean=false
varwho:String?=null
varimages:List?=null
/**
*妹子小图
*/
funmeiziSmallUrl():String{
valmeizi=url
returnmeizi.replace("large","small")
}
}
interfaceApiservice{
@GET("data/{type}/10/{page}")
fungetGank(@Path("type")type:String,@Path("page")page:Int):Observable>>
}
objectApi{
valapiservice:Apiservicebylazy{
Log.d("Api","apiservicecreatelazy")
RetrofitUtil.retrofit.create(Apiservice::class.java)
}
}
使用
overridefunloadData(){
Rx.get(Api.apiservice.getGank(getType(),mIntPage),this).subscribe(object:HttpObserver>(){
overridefunonSuccess(t:List?){
//getDataSuccess(t)
}
overridefunonError(code:Int,msg:String?){
super.onError(code,msg)
//getDataFailed()
}
})
}
使用了Rxlifecycle绑定生命周期来处理可能发生的内存泄漏问题,Fragment跟Activity需要继承Rx相应的基类。
练手项目
MeiziktGank.ioAndroid客户端,使用Kotlin+Retrofit2+RxJava
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。