须要的依赖java
// 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"复制代码
代码react
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()
}
}复制代码
简要说明android
initOkhttpClient()
方法中的日志拦截器打印出来的header中没有包括拦截器的header,可是从Debug结果来看,拦截器里面的header头确实是加上了,并且是能够修改的,Constants.TOKEN
是object
单例类Constants中的一个var变量。能够在代码中修改,修改以后拦截器中的header也会跟着修改。api
主要代码ide
// 顺序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())
}
}复制代码
请求接口gradle
interface TestService {
@FormUrlEncoded
@POST("/api/login")
fun getLoginUser(@FieldMap map: Map<String, String>): Flowable<UserBean>
}复制代码
简要说明ui
在主要代码中我使用了一个LinkedHashMap
,这是由于咱们的后台要求请求的前几个参数是有序的,因此要添加到一个顺序map集合中。
UserBean
是一个对象,由于刚开始添加了字符串与Gson的解析器,因此能够直接使用对象或者是类来操做。相应的在1主要代码中的s ->中的s也至关因而这个对象或者是字符串。spa