美文网首页
Kotlin+Rxjava+Retrofit+okHttp网络请

Kotlin+Rxjava+Retrofit+okHttp网络请

作者: Method | 来源:发表于2021-06-08 15:53 被阅读0次

    [toc]

    依赖

    ext.kotlin_version = "1.5.0"
    ext.retrofit_version = "2.9.0"
    ext.ok_http_version = "3.4.1"
    ext.rx_kotlin_version = '3.0.1'
    ext.rx_android_version ='3.0.0'
    
    implementation "com.squareup.okhttp3:okhttp:$ok_http_version"
    implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
    implementation "com.squareup.okhttp3:logging-interceptor:$ok_http_version"
    implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
    implementation "com.squareup.retrofit2:adapter-rxjava3:$retrofit_version"
    
    implementation "io.reactivex.rxjava3:rxkotlin:$rx_kotlin_version"
    implementation "io.reactivex.rxjava3:rxandroid:${rx_android_version}"
    

    封装步骤

    1.配置Retrofit,okHttpClient

    /**
     * create by Admin in 2021/6/8
     *
     * @Description : retrofit封装
     **/
    class RetrofitFactory {
        private lateinit var retrofit:Retrofit
        companion object{
            //单例
            val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
                RetrofitFactory()
            }
        }
    
        /**
         * 组装retrofit对象
         */
        init {
            retrofit = Retrofit.Builder()
                .baseUrl(NetContants.BASE_URL)
                .client(getClient())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .build()
        }
    
        /**
         * 组装client
         */
        private fun getClient(): OkHttpClient {
            return OkHttpClient.Builder()
                .writeTimeout(10,TimeUnit.SECONDS)
                .readTimeout(10,TimeUnit.SECONDS)
                .connectTimeout(10,TimeUnit.SECONDS)
                .addInterceptor(getLogInterceptor())
                .build()
    
        }
    
        /**
         * log 拦截器
         */
        private fun getLogInterceptor(): Interceptor {
            val logInterceptor = HttpLoggingInterceptor()
            logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
            return logInterceptor
        }
    
        /**
         * service
         */
        fun <T> create(service:Class<T>):T{
            return retrofit.create(service)
        }
    
    }
    

    2.创建请求接口apiService

    /**
     * create by Admin in 2021/6/8
     *
     * @Description : retrofit抽象接口
     **/
    interface UserApiService {
        //登录接口
        @FormUrlEncoded
        @POST("user/login")
        fun login(@Field("userName") userName: String,
                  @Field("password") password: String): Observable<BaseRep<LoginBean>>
    }
    

    2.1返回数据封装

    /**
     * create by Admin in 2021/6/8
     *
     * @Description : 接口返回格式
     **/
    data class BaseRep<T>(val data:T,val errorCode:Int,val errorMsg:String)
    

    3.请求接口

    /**
     * create by Admin in 2021/6/8
     *
     * @Description : 用户模块接口请求
     **/
    class UserServiceImpl : UserService {
        val userResposity by lazy { UserRepository() }
        override fun login(userName: String, pwd: String) {
            println("loading开始")
            userResposity.login(userName, pwd).covert()
                .execute(object : BaseObserver<LoginBean>() {
                    override fun onNext(t: LoginBean?) {
                        super.onNext(t)
                        println("登录成功")
                    }
                })
        }
    }
    

    3.1返回数据转换

    /*
    *  返回数据转换
    */
    fun <T> Observable<BaseRep<T>>.covert():Observable<T>{
        return this.flatMap(object :Function<BaseRep<T>,Observable<T>>{
            override fun apply(t: BaseRep<T>): Observable<T> {
                if(t.errorCode != 0){
                    return Observable.error(BaseException(t.errorCode,t.errorMsg))
                }else{
                    return Observable.just(t.data)
                }
            }
        })
    }
    

    3.2rx封装

    /*
    *  Observable扩展
    */
    fun <T> Observable<T>.execute(observer:BaseObserver<T>){
        this.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer)
    }
    
    

    3.3错误处理

    open class BaseObserver<T> : Observer<T> {
        override fun onSubscribe(d: Disposable?) {
    
        }
    
        override fun onNext(t: T?) {
        }
    
        override fun onError(e: Throwable?) {
            if(e is BaseException){
                println(e.errorMsg)
            }else{
                val errorMsg = NetExceptionUtils.exceptionHandler(e!!)
                println(errorMsg)
            }
            println("loading结束")
        }
    
        override fun onComplete() {
            println("loading结束")
        }
    }
    
    /**
     * create by Admin in 2021/6/9
     *
     * @Description : 异常信息封装
     **/
    object NetExceptionUtils {
    
        fun exceptionHandler(e: Throwable): String {
            var errorMsg = "未知错误"
            when (e) {
                is UnknownHostException -> {
                    errorMsg = "网络不可用"
                }
                is SocketTimeoutException -> {
                    errorMsg = "请求网络超时"
                }
                is HttpException -> {
                    val httpException = e as HttpException
                    errorMsg = covertStatusCode(httpException)
                }
                is ParseException,
                is JSONException -> {
                    errorMsg = "数据解析错误"
                }
            }
            return errorMsg
        }
    
        private fun covertStatusCode(httpException: HttpException): String {
            var msg = ""
            when (httpException.code()) {
                in 500 until 600 -> {
                    msg = "服务器处理请求错误"
                }
                in 400 until 500 -> {
                    msg = "服务器无法处理请求"
                }
                in 300 until 400 -> {
                    msg = "请求被重定向到其他界面"
                }
                else -> {
                    msg = httpException.message()
                }
            }
            return msg
        }
    }
    

    执行结果

    D/OkHttp: {"data":null,"errorCode":-1,"errorMsg":"账号密码不匹配!"}
        <-- END HTTP (66-byte body)
    I/System.out: 账号密码不匹配!
        loading结束
    

    参考资料

    api地址
    源码地址

    相关文章

      网友评论

          本文标题:Kotlin+Rxjava+Retrofit+okHttp网络请

          本文链接:https://www.haomeiwen.com/subject/mzhjeltx.html