Kotlin中Retrofit網絡請求簡單封裝

使用Kotlin簡單的對Retrofit+RxJava大多數普通請求進行封裝java

提示:若是對Kotlin,RxLifecycle,Retrofit,RxJava等不太瞭解的小夥伴能夠參考網上的基礎資料react

1.慣例先添加依賴android

//Retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    //RxJava
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.0.1'
    //rxlifecycle
    implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
    //解析相關
    implementation 'com.alibaba:fastjson:1.2.34'
    //kotlin
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    //Kotlin反射庫 Kotlin使用反射則添加
    implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
複製代碼

2.封裝請求Retrofit接口json

一般來講咱們一個應用可能只有一個BaseUrl,此處只對Retrofit接口進行了單例封裝bash

public class RetrofitUtils {

    private RetrofitUtils() {
    }

    private static class Tool {

        static IApiServer defaultServer = initRetrofitServer(NetConfig.BASE_URL);

        static IApiServer initRetrofitServer(String baseUrl) {
            int DEFAULT_TIME = 15;    //默認超時時間

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.readTimeout(DEFAULT_TIME, TimeUnit.SECONDS);
            builder.connectTimeout(DEFAULT_TIME, TimeUnit.SECONDS);
            //        builder.addInterceptor(new LoggingInterceptor());//使用自定義的Log攔截器
            OkHttpClient client = builder.build();
            return new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(FastJsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(client)
                    .build()
                    .create(IApiServer.class);
        }
    }

    public static IApiServer getDefaultServer() {
        return Tool.defaultServer;
    }

}
複製代碼

3.請求響應的封裝app

對於有格式規律的返回結果進行封裝,好比如下格式ide

{
    "code": "200",
    "data": {}
    "msg": "成功"
}
複製代碼

每次請求都會固定的返回code和msg,而data纔是真正的數據。定義一個實體類,格式以下:函數

public class BaseResponse<T> {
    @JSONField(name = "status")
    public int status;
    @JSONField(name = "data")
    public T data;
    @JSONField(name = "msg")
    public String msg;
}
複製代碼

4.請求函數的封裝ui

ApiCodeType中封裝了部分狀態和錯誤的tips 你們能夠根據本身的狀況進行編寫this

對於狀態攔截若是業務很複雜你們也能夠抽取成攔截器等方式

object RetrofitUtilsKt {

    /**
     *   Activity 中綁定聲明週期 處理數據請求統一函數
     *   @param observable 請求接口Observable實例
     *   @param lifecycleProvider 可謂空 若是爲空不綁定聲明週期
     *   @param showDialog 是否顯示LoadView 默認顯示
     *   @param onNext 成功回調
     *   @param onError 失敗回調
     *   @param showDialog 是否顯示loadView
     */
    fun <T> runRxA(observable: Observable<T>,
                   lifecycleProvider: LifecycleProvider<ActivityEvent>?,
                   onNext: (data: T) -> Unit,
                   onError: (codeType: ApiCodeType) -> Unit,
                   showDialog: Boolean = true): Disposable {
        var dialog: AlertDialog? = null
        //綁定lifecycle
        val realObservable = if (lifecycleProvider != null)
            observable.compose(lifecycleProvider.bindUntilEvent(ActivityEvent.DESTROY))
        else
            observable

        return realObservable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe {
                    //請求以前 顯示loadView等操做
                    if (lifecycleProvider is Activity && showDialog) {
                        dialog = DefaultUtils.showProgressDialog(lifecycleProvider)
                    }
                }
                .subscribe(Consumer<T> {
                    dialog?.apply { dismiss() }
                    //數據錯誤
                    if (it == null || (it is BaseResponse<*> && it.data == null)) {
                        onError(ApiCodeType.DATA_ERROR)
                        return@Consumer
                    }
                    //根據業務需求攔截部分狀態
                    if (it is BaseResponse<*>) {
                        when (it.status) {
                            ApiCodeType.LOGON_EXPIRED.code ->{ //攔截代碼 }
                            else -> onNext(it)
                        }
                    } else {
                        onNext(it)
                    }
                }, Consumer<Throwable> {
                    dialog?.apply { dismiss() }
                    onError(ApiCodeType.OTHER_ERROR)
                })
    }
}
複製代碼

此處只展現了綁定Activity生命週期的函數,若是你們須要綁定Fragment生命週期更換LifecycleProvider的泛型爲FragmentEvent便可。

5.擴展函數的封裝

對於普通簡單請求一般咱們只關心三要素,請求接口(包括參數)、關聯生命週期(Activity等)、結果回調。

在Kotlin中可對任意類型添加擴展函數,根據此特性咱們對必要類型之一(請求接口)編寫如下函數便於使用:

fun <T> Observable<T>.runRxA(lifecycleProvider: LifecycleProvider<ActivityEvent>?,
                             onNext: (data: T) -> Unit,
                             onError: (codeType: ApiCodeType) -> Unit,
                             showDialog: Boolean = true) =
        RetrofitUtilsKt.runRxA(this, lifecycleProvider, onNext, onError, showDialog)
複製代碼

6.使用

Kotlin中單參數lamdba無需顯示聲明,可用it表示,代碼中註釋爲當前it類型。

RetrofitUtils
                .getDefaultServer()
                .getContractInformationEdit(bean)
                .runRxA(this, { 
                //成功
                //it:BaseResponse<ContractInformationBean>
                }, {
                //失敗
                //it:ApiCodeType
                    toast(it.msg)
                })
複製代碼

結尾

但願本文對各爲小夥伴有所幫助,若是錯誤或者疑問歡迎留言指出。:)

相關文章
相關標籤/搜索