Kotlin + Retrofit + RxJava简单封装使用详解
程序员文章站
2023-12-20 20:53:28
本文介绍了kotlin + retrofit + rxjava简单封装使用详解,分享给大家,具体如下:
实例化retrofit
object retrofi...
本文介绍了kotlin + retrofit + rxjava简单封装使用详解,分享给大家,具体如下:
实例化retrofit
object retrofitutil { val connect_time_out = 30//连接超时时长x秒 val read_time_out = 30//读数据超时时长x秒 val write_time_out = 30//写数据接超时时长x秒 val retrofit: retrofit by lazy { log.d("retrofitutil", "retrofit init lazy") retrofit.builder() .baseurl("http://gank.io/api/") //本文以github api为例 .addconverterfactory(gsonconverterfactory.create()) .addcalladapterfactory(rxjava2calladapterfactory.create()) .client(getokhttpclient()) .build() } private fun getokhttpclient(): okhttpclient { val builder = 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 -> val time = (system.currenttimemillis() / 1000).tostring() + "" val requestbuilder = chain.request().newbuilder() requestbuilder.addheader("time", time) chain.proceed(requestbuilder.build()) } return builder.build() } }
返回数据封装
class response<t> { var error: boolean = false var results: t? = null }
demo中用了gank.io的开发api,之前一般项目的返回格式是code + message + t的格式。
api接口错误/异常统一处理类
class apiexception : exception { var code: int = 0//错误码 var msg: 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:
class exceptionfunction<t> : function<throwable, observable<t>> { override fun apply(@nonnull throwable: throwable): observable<t> { log.e("exceptionfunction", throwable.message) return observable.error(exceptionengine().handleexception(throwable)) } } /** * 错误/异常处理工具 */ class exceptionengine { val un_known_error = 1000//未知错误 val analytic_server_data_error = 1001//解析(服务器)数据错误 val connect_error = 1002//网络连接错误 val time_out_error = 1003//网络连接超时 fun handleexception(e: throwable): apiexception { val ex: apiexception if (e is apiexception) { //服务器返回的错误 return e } else if (e is httpexception) { //http错误 ex = apiexception(e, e.code()) ex.msg = "网络错误:" + ex.code return ex } else if (e is jsonparseexception || e is jsonexception || e is parseexception || e is malformedjsonexception) { //解析数据错误 ex = apiexception(e, analytic_server_data_error) ex.msg = "解析错误" return ex } else if (e is connectexception) {//连接网络错误 ex = apiexception(e, connect_error) ex.msg = "连接失败" return ex } else if (e is sockettimeoutexception) {//网络超时 ex = apiexception(e, time_out_error) ex.msg = "网络超时" return ex } else { //未知错误 ex = apiexception(e, un_known_error) ex.msg = e.message return ex } } }
封装请求处理
object rx { /** * rxlifecycle绑定生命周期 */ fun <t, e> get(observable: observable<response<t>>, lifecycleprovider: lifecycleprovider<e>): observable<t> { // 请求绑定生命周期,防止内存泄漏,同时返回回调之后页面已销毁造成的空指针错误 if (lifecycleprovider is rxappcompatactivity) { val rxappcompatactivity = lifecycleprovider as rxappcompatactivity observable.compose(rxappcompatactivity.binduntilevent(activityevent.destroy)) } else if (lifecycleprovider is rxfragment) { val rxfragment = lifecycleprovider as rxfragment observable.compose(rxfragment.binduntilevent(fragmentevent.destroy)) } return observable .compose(handleresult()) .onerrorresumenext(exceptionfunction()) } /** * 部分后台请求 */ fun <t> get(observable: observable<response<t>>): observable<t> { return observable .compose(handleresult()) .onerrorresumenext(exceptionfunction()) } private class handleresult<t> : observabletransformer<response<t>, t> { override fun apply(upstream: observable<response<t>>): observablesource<t> { return upstream.flatmap { response -> createresult(response) } .subscribeon(schedulers.io()) .unsubscribeon(schedulers.io()) .observeon(androidschedulers.mainthread()) } } private fun <t> createresult(response: response<t>): observable<t> { return observable.create({ subscriber -> if (response.error) throw apiexception(-1, "服务器异常") // 一般来说,自己的服务器异常会返回相应的code和message else response.results?.let { subscriber.onnext(response.results!!) } ?: subscriber.oncomplete() }) } }
定义httpobserver统一处理返回
abstract class httpobserver<t> : observer<t> { /** * 标记是否为特殊情况 */ private var resultnull: boolean = true override fun oncomplete() { // 特殊情况:当请求成功,但t == null时会跳过onnext,仍需当成功处理 if (resultnull) onsuccess(null) } override fun onsubscribe(d: disposable) { // 可在此处加上dialog } override fun onerror(e: throwable) { if (e is apiexception) { onerror(e.code, e.msg) } else { onerror(0, e.message) } } override fun onnext(t: t) { resultnull = false onsuccess(t) } abstract fun onsuccess(t: t?) /** * 统一处理失败,比如登录失效等 * * @param code * @param msg */ open fun onerror(code: int, msg: string?) { } }
api
class result { var _id: string? = null var createdat: string? = null var desc: string? = null var publishedat: string? = null var source: string? = null var type: string? = null var url: string = "" var isused: boolean = false var who: string? = null var images: list<string>? = null /** * 妹子小图 */ fun meizismallurl(): string { val meizi = url return meizi.replace("large", "small") } } interface apiservice { @get("data/{type}/10/{page}") fun getgank(@path("type") type: string, @path("page") page: int): observable<response<list<result>>> } object api { val apiservice: apiservice by lazy { log.d("api", "apiservice create lazy") retrofitutil.retrofit.create(apiservice::class.java) } }
使用
override fun loaddata() { rx.get(api.apiservice.getgank(gettype(), mintpage), this).subscribe(object : httpobserver<list<result>>() { override fun onsuccess(t: list<result>?) { //getdatasuccess(t) } override fun onerror(code: int, msg: string?) { super.onerror(code, msg) //getdatafailed() } }) }
使用了rxlifecycle绑定生命周期来处理可能发生的内存泄漏问题,fragment跟activity需要继承rx相应的基类。
练手项目
meizikt gank.io android客户端,使用kotlin + retrofit2 + rxjava
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。