須要的依賴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