一、引入
- 使用Kotlin以单例形式做了一个简单的Retrofit封装,因为业务需要,要将token添加到请求头当中,所以使用了okhttp的拦截器做了简单封装,使其能够满足当前的业务需求,可以能够动态修改拦截器中的请求头信息。额(⊙﹏⊙)描述实在是写不了,还是看代码吧。
- 如果对于Retrofit或RxJava还不是很了解可以看一下我的博客早些时候的文章了解一下。
二、封装
- 需要的依赖 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14- // retrofit2 
 implementation "com.squareup.retrofit2:retrofit:2.3.0"
 // Gson
 implementation "com.squareup.retrofit2:converter-gson:2.3.0"
 // 字符串
 implementation "com.squareup.retrofit2:converter-scalars:2.3.0"
 // RxJava
 implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
 // okhttp
 implementation "com.squareup.okhttp3:okhttp:3.8.0"
 implementation "com.squareup.okhttp3:logging-interceptor:3.8.0"
 // RxJava2
 implementation "io.reactivex.rxjava2:rxandroid:2.0.1"
 implementation "io.reactivex.rxjava2:rxjava:2.1.3"
- 代码 - 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
 53
 54
 55
 56- object RetrofitClient { 
 /**
 * by lazy 懒加载(延迟加载)
 */
 private val mRetrofit by lazy { createRetrofit() }
 /**
 * 默认接口实现类的实例
 */
 val gClient by lazy { createService(TestService::class.java) }
 /**
 * 生成接口实现类的实例
 */
 fun <T> createService(serviceClass: Class<T>): T {
 return mRetrofit.create(serviceClass)
 }
 private fun createRetrofit(): Retrofit {
 return Retrofit.Builder()
 .baseUrl(Constants.BASE_URL)
 // 设置OkHttpclient
 .client(initOkhttpClient())
 // RxJava2
 .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
 // 字符串
 .addConverterFactory(ScalarsConverterFactory.create())
 // Gson
 .addConverterFactory(GsonConverterFactory.create())
 .build()
 }
 /**
 * 每次请求都会走拦截器
 *
 * 只需要修改Constants.TOKEN就可以
 */
 private fun initOkhttpClient(): OkHttpClient {
 val builder = OkHttpClient.Builder()
 if (Constants.LOG_FLAG) {
 // OkHttp日志拦截器
 builder.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
 }
 builder.addInterceptor { chain ->
 val original = chain.request()
 val request = original.newBuilder()
 // 设置请求头,从Debug中看到修改Constants.TOKEN请求header头也会修改
 .header("Authorization", Constants.TOKEN)
 .method(original.method(), original.body())
 .build()
 return@addInterceptor chain.proceed(request)
 }
 return builder.build()
 }
 }
- 简要说明 - initOkhttpClient()方法中的日志拦截器打印出来的header中没有包括拦截器的header,但是从Debug结果来看,拦截器里面的header头确实是加上了,而且是可以修改的,- Constants.TOKEN是- object单例类Constants中的一个var变量。可以在代码中修改,修改之后拦截器中的header也会跟着修改。
二、使用
- 主要代码 - 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- // 顺序map 
 var map = LinkedHashMap<String, String>()
 map.put("username", "sdwfqin")
 map.put("password", "123123")
 // 这里调用的是上述封装类中默认接口实现类的实例gClient
 RetrofitClient.gClient
 // 调用请求接口中的方法
 .getLoginUser(map)
 // 线程切换,(请求在io,操作在主)
 .compose(SdUtils.rxSchedulerHelper())
 .subscribe(
 // 第一个相当于OnNext()
 { s ->
 log_e(s.toString())
 main_tv.text = s.toString()
 if (s.ret == 0) {
 showToast("登录成功${s.data.user.usertoken}")
 } else {
 showToast("登录失败${s.msg}")
 }
 hideProgress()
 },
 // 第二个相当于OnError()
 { e ->
 // e是一个异常
 log_e(e.toString())
 httpError()
 }
 )
 ----------------------
 // 线程切换的代码
 /**
 * 统一线程处理
 * @param
 * @return
 */
 fun <T> rxSchedulerHelper(): FlowableTransformer<T, T> { //compose简化线程
 return FlowableTransformer { observable ->
 observable.subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 }
 }
- 请求接口 - 1 
 2
 3
 4
 5
 6- interface TestService { 
 
 
 fun getLoginUser( map: Map<String, String>): Flowable<UserBean>
 }
- 简要说明 - 在主要代码中我使用了一个 - LinkedHashMap,这是因为我们的后台要求请求的前几个参数是有序的,所以要添加到一个顺序map集合中。
 - UserBean是一个对象,因为刚开始添加了字符串与Gson的解析器,所以可以直接使用对象或者是类来操作。相应的在1主要代码中的s ->中的s也相当于是这个对象或者是字符串。