本文介绍了kotlin + retrofit + rxjava简单封装使用详解,分享给大家,具体如下:
实例化retrofit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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() } } |
返回数据封装
1
2
3
4
|
class response<t> { var error: boolean = false var results: t? = null } |
demo中用了gank.io的开发api,之前一般项目的返回格式是code + message + t的格式。
api接口错误/异常统一处理类
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
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 } } } |
封装请求处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
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统一处理返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
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) } } |
使用
1
2
3
4
5
6
7
8
9
10
11
12
|
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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://www.jianshu.com/p/e5f2bb8738db