栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

RxHttp网络请求

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

RxHttp网络请求

RxHttp

项目地址:kongpf8848/RxHttp 

简介: 基于 RxJava2+Retrofit+OkHttp4.x 封装的网络请求类库,亮点多多,完美兼容 MVVM(ViewModel,LiveData),天生支持网络请求和生命周期绑定,天生支持多 BaseUrl,支持文件上传下载进度监听,支持断点下载,支持 Glide 和网络请求公用一个 OkHttpClient

更多:作者   提 Bug   

标签:

基于 RxJava2+Retrofit 2.9.0+OkHttp 4.9.0 实现的轻量级,完美兼容 MVVM 架构的网络请求封装类库,小巧精致,简单易用,网络请求原来如此简单:smirk::smirk::smirk:

亮点
  • 代码量极少,类库体积不足 100kb,但足以胜任大部分 APP 的网络请求任务,浓缩的都是精华啊^

  • 完美兼容 MVVM,MVC 架构,兼容 Kotlin 和 Java,Kotlin+MVVM+RxHttp 结合起来使用更酸爽,MVVM 官方推荐,抱紧 Google 大腿就对了

  • 完美解决泛型类型擦除的棘手问题,还原泛型的真实类型

  • 天生支持网络请求和 Activity,Fragment 生命周期绑定,界面销毁时自动取消网络请求回调

  • 天生支持多 BaseUrl,支持动态传入 Url

  • 支持自定义 OkHttpClient.Builder,可高度自定义网络请求参数,支持 Https 证书单向校验(客户端校验服务端证书)

  • 支持 Glide 等和 Http 请求公用一个 OkHttpClient,充分利用 OkHttpClient 的线程池和连接池,大部分情况下一个 App 一个 OkHttpClient 就够了

  • 支持 GET,POST,PUT,DELETE 等请求方式,支持文件上传及进度监听,支持同时上传多个文件,支持 Uri 上传

  • 支持文件下载及进度监听,支持大文件下载,支持断点下载

使用要求

项目基于 AndroidX,Java8+,minSdkVersion>=21

使用
  • 在项目根目录的 build.gradle 文件中添加:
    allprojects {
      repositories {
          mavenCentral()
      }
    }
    
  • 在具体 Module 的 build.gradle 文件中添加:
    implementation 'io.github.kongpf8848:RxHttp:1.0.12'
    
配置(可选)
  RxHttpConfig.getInstance()
    
    .maxRetries(3)
    
    .retryDelayMillis(200)
    
     //.certificate(AssetUtils.openFile(applicationContext,"xxx.cer"))
    
    .getBuilder().apply {
        connectTimeout(60, TimeUnit.SECONDS)
        readTimeout(60, TimeUnit.SECONDS)
        writeTimeout(60, TimeUnit.SECONDS)
        
        if (BuildConfig.DEBUG) {
            addInterceptor(FixHttpLoggingInterceptor().apply {
                level = FixHttpLoggingInterceptor.Level.BODY
            })
        }
    }
基础使用
  • GET/POST/PUT/DELETE/上传请求
   RxHttp.getInstance()
    
    .get(context)
    
    .url("xxx")
    
    .params(map)
    
    .tag("xxx")
    
    .enqueue(object : HttpCallback() {
        
        override fun onStart() {

        }

        
        override fun onNext(response: xxx?) {

        }

        
        override fun onError(e: Throwable?) {

        }

        
        override fun onComplete() {

        }

        
        override fun onProgress(readBytes: Long, totalBytes: Long) {

        }
    })
  • 下载请求
   RxHttp.getInstance()
      
      .download(context)
      
      .dir(dir)
      
      .filename(filename)
      
      .breakpoint(true)
      
      .url(url)
      
      .tag(null)
      
      .enqueue(object: DownloadCallback() {
          
          override fun onStart() {

          }

          
          override fun onNext(response: DownloadInfo?) {

          }

          
          override fun onError(e: Throwable?) {

          }

          
          override fun onComplete() {

          }

          
          override fun onProgress(readBytes: Long, totalBytes: Long) {

          }

      })
  • 取消请求
    
    RxHttp.getInstance().cancelRequest(tag)
项目实战

此处假设服务端返回的数据格式为{"code":xxx,"data":T,"msg":""},其中 code 为响应码,整型,等于 200 时为成功,其余为失败,data 对应的数据类型为泛型(boolean,int,double,String,对象{ },数组[ ]等类型)

 {
    "code": 200,
    "data":T,
    "msg": ""
}

对应的 Response 类为

class TKResponse(val code:Int,val msg: String?, val data: T?) : Serializable {
    companion object{
        const val STATUS_OK=200
    }
    fun isSuccess():Boolean{
        return code== STATUS_OK
    }
}
  • MVC 项目

    • 定义 MVCHttpCallback,用于将网络请求结果回调给 UI 界面
```kotlin

abstract class MVCHttpCallback {

    private val type: Type

    init {
        val arg = TypeUtil.getType(javaClass)
        type = TypeBuilder
                .newInstance(TKResponse::class.java)
                .addTypeParam(arg)
                .build()
    }

    fun getType(): Type {
        return this.type
    }

    
    open fun onStart() {}

    
    abstract fun onSuccess(result: T?)

    
    abstract fun onFailure(code: Int, msg: String?)

    
    open fun onProgress(readBytes: Long, totalBytes: Long) {}

    
    open fun onComplete() {}

}

   * 定义网络接口,封装 GET/POST 等网络请求


   ```kotlin
   object MVCApi {

       
       inline fun  httpGet(
               context: Context,
               url: String,
               params: Map?,
               tag: Any? = null,
               callback: MVCHttpCallback
       ) {
           RxHttp.getInstance().get(context)
                   .url(url)
                   .params(params)
                   .tag(tag)
                   .enqueue(simpleHttpCallback(callback))
       }

       
       inline fun  httpPost(
               context: Context,
               url: String,
               params: Map?,
               tag: Any? = null,
               callback: MVCHttpCallback
       ) {
           RxHttp.getInstance().post(context)
                   .url(url)
                   .params(params)
                   .tag(tag)
                   .enqueue(simpleHttpCallback(callback))
       }

       ......

        inline fun  simpleHttpCallback(callback: MVCHttpCallback): HttpCallback> {
           return object : HttpCallback>(callback.getType()) {
               override fun onStart() {
                   super.onStart()
                   callback.onStart()
               }

               override fun onNext(response: TKResponse?) {
                   if (response != null) {
                       if (response.isSuccess()) {
                           callback.onSuccess(response.data)
                       } else {
                           return onError(ServerException(response.code, response.msg))
                       }

                   } else {
                       return onError(NullResponseException(TKErrorCode.ERRCODE_RESPONSE_NULL, TKErrorCode.ERRCODE_RESPONSE_NULL_DESC))
                   }

               }

               override fun onError(e: Throwable?) {
                   handleThrowable(e).run {
                       callback.onFailure(first, second)
                   }
               }

               override fun onComplete() {
                   super.onComplete()
                   callback.onComplete()
               }

               override fun onProgress(readBytes: Long, totalBytes: Long) {
                   super.onProgress(readBytes, totalBytes)
                   callback.onProgress(readBytes, totalBytes)
               }
           }
       }
 * 在 View 层如 Activity 中调用网络接口


 ```kotlin
 MVCApi.httpGet(
     context = baseActivity,
     url = TKURL.URL_GET,
     params = null,
     tag = null, 
     callback = object : MVCHttpCallback>() {
     override fun onStart() {
         LogUtils.d(TAG, "onButtonGet onStart() called")
     }

     override fun onSuccess(result: List?) {
         Log.d(TAG, "onButtonGet onSuccess() called with: result = $result")
     }

     override fun onFailure(code: Int, msg: String?) {
         Log.d(TAG, "onButtonGet onFailure() called with: code = $code, msg = $msg")
     }

     override fun onComplete() {
         Log.d(TAG, "onButtonGet onComplete() called")
     }

 })
 ```

 **具体使用可以参考 demo 代码,demo 中有详细的示例演示 MVC 项目如何使用 RxHttp**
  • MVVM 项目

    • 定义 Activity 基类 BaseMvvmActivity

      abstract class BaseMvvmActivity : AppCompatActivity(){
      
       lateinit var viewModel: VM
       lateinit var binding: VDB
      
       protected abstract fun getLayoutId(): Int
      
       final override fun onCreate(savedInstanceState: Bundle?) {
           onCreateStart(savedInstanceState)
           super.onCreate(savedInstanceState)
           binding = DataBindingUtil.setContentView(this, getLayoutId())
           binding.lifecycleOwner = this
           createViewModel()
           onCreateEnd(savedInstanceState)
       }
      
       protected open fun onCreateStart(savedInstanceState: Bundle?) {}
       protected open fun onCreateEnd(savedInstanceState: Bundle?) {}
      
       
       private fun createViewModel() {
           val type = findType(javaClass.genericSuperclass)
           val modelClass = if (type is ParameterizedType) {
               type.actualTypeArguments[0] as Class
           } else {
               BaseViewModel::class.java as Class
           }
           viewModel = ViewModelProvider(this).get(modelClass)
       }
      
       private fun findType(type: Type): Type?{
           return when(type){
               is ParameterizedType -> type
               is Class<*> ->{
               findType(type.genericSuperclass)
               }
               else ->{
               null
               }
           }
       }
      
      }
      
    • 定义 ViewModel 的基类 BaseViewModel

      open class BaseViewModel(application: Application) : AndroidViewModel(application) {
      
       
       protected val networkbaseRepository: NetworkRepository = NetworkRepository.instance
      
       
       protected var context: Context = application.applicationContext
      
      }
      
    • 定义网络仓库,封装网络接口 ```kotlin class NetworkRepository private constructor() {

      companion object {

       val instance = NetworkRepository.holder
      

      }

      private object NetworkRepository {

       val holder = NetworkRepository()
      

      }

      inline fun wrapHttpCallback(): MvvmHttpCallback {

       return object : MvvmHttpCallback() {
      
       }
      

      }

      inline fun newCallback(liveData: MutableLiveData>): HttpCallback> {

       val type = wrapHttpCallback().getType()
       return object : HttpCallback>(type) {
           override fun onStart() {
           liveData.value = TKState.start()
           }
      
           override fun onNext(response: TKResponse?) {
           liveData.value = TKState.response(response)
           }
      
           override fun onError(e: Throwable?) {
           liveData.value = TKState.error(e)
           }
      
           override fun onComplete() {
      
           
           }
      
           override fun onProgress(readBytes: Long, totalBytes: Long) {
           liveData.value = TKState.progress(readBytes, totalBytes)
           }
       }
      

      }

      inline fun httpGet(

       context: Context,
       url: String,
       params: Map?,
       tag: Any? = null
      

      ): MutableLiveData> {

       val liveData = MutableLiveData>()
       RxHttp.getInstance()
           .get(context)
           .url(url)
           .params(params)
           .tag(tag)
           .enqueue(newCallback(liveData))
       return liveData
      

      }

    inline fun  httpPost(
        context: Context,
        url: String,
        params: Map?,
        tag: Any? = null
    ): MutableLiveData> {
        val liveData = MutableLiveData>()
        RxHttp.getInstance().post(context)
            .url(url)
            .params(params)
            .tag(tag)
            .enqueue(newCallback(liveData))
        return liveData
    }

    inline fun  httpPostForm(
        context: Context,
        url: String,
        params: Map?,
        tag: Any? = null
    ): MutableLiveData> {
        val liveData = MutableLiveData>()
        RxHttp.getInstance().postForm(context)
            .url(url)
            .params(params)
            .tag(tag)
            .enqueue(newCallback(liveData))
        return liveData
    }

    inline fun  httpPut(
        context: Context,
        url: String,
        params: Map?,
        tag: Any? = null
    ): MutableLiveData> {
        val liveData = MutableLiveData>()
        RxHttp.getInstance().put(context)
            .url(url)
            .params(params)
            .tag(tag)
            .enqueue(newCallback(liveData))
        return liveData
    }

    inline fun  httpDelete(
        context: Context,
        url: String,
        params: Map?,
        tag: Any? = null
    ): MutableLiveData> {
        val liveData = MutableLiveData>()
        RxHttp.getInstance().delete(context)
            .params(params)
            .url(url)
            .tag(tag)
            .enqueue(newCallback(liveData))
        return liveData
    }


    
    inline fun  httpUpload(
        context: Context,
        url: String,
        params: Map?,
        tag: Any? = null
    ): MutableLiveData> {
        val liveData = MutableLiveData>()
        RxHttp.getInstance().upload(context)
            .url(url)
            .params(params)
            .tag(tag)
            .enqueue(newCallback(liveData))
        return liveData
    }


    
    fun httpDownload(context: Context, url: String, dir: String, filename: String, callback: DownloadCallback, md5: String? = null, breakPoint: Boolean = true, tag: Any? = null) {
        RxHttp.getInstance().download(context).dir(dir).filename(filename).breakpoint(breakPoint).md5(md5).url(url).tag(tag).enqueue(callback)
    }

}
 ```
 * 定义 TKState 类,用于将网络回调转化为 LiveData

 ```kotlin
 
class TKState {

    var state: Int = 0
    var code = TKErrorCode.ERRCODE_UNKNOWN
    var msg: String? = null
    var data: T? = null
    var progress: Long = 0
    var total: Long = 0

    @JvmOverloads
    constructor(state: Int, data: T? = null, msg: String? = "") {
        this.state = state
        this.data = data
        this.msg = msg
    }

    constructor(state: Int, throwable: Throwable?) {
        this.state = state
        handleThrowable(throwable).run {
            this@TKState.code = first
            this@TKState.msg = second
        }
    }

    constructor(state: Int, progress: Long, total: Long) {
        this.state = state
        this.progress = progress
        this.total = total
    }

    fun handle(handleCallback: HandleCallback.() -> Unit) {
        val callback = HandleCallback()
        callback.apply(handleCallback)
        when (state) {
            START -> {
            callback.onStart?.invoke()
            }
            SUCCESS -> {
            callback.onSuccess?.invoke(data)
            }
            FAIL -> {
            callback.onFailure?.invoke(code, msg)
            }
            PROGRESS -> {
            callback.onProgress?.invoke(progress, total)
            }
        }
        if (state == SUCCESS || state == FAIL) {
            callback.onComplete?.invoke()
        }
    }

    open class HandleCallback {
        var onStart: (() -> Unit)? = null
        var onSuccess: ((T?) -> Unit)? = null
        var onFailure: ((Int, String?) -> Unit)? = null
        var onComplete: (() -> Unit)? = null
        var onProgress: ((Long, Long) -> Unit)? = null

        fun onStart(callback: (() -> Unit)?) {
            this.onStart = callback
        }

        fun onSuccess(callback: ((T?) -> Unit)?) {
             this.onSuccess = callback
        }

        fun onFailure(callback: ((Int, String?) -> Unit)?) {
            this.onFailure = callback
        }

        fun onComplete(callback: (() -> Unit)?) {
            this.onComplete = callback
        }

        fun onProgress(callback: ((Long, Long) -> Unit)?) {
            this.onProgress = callback
        }
    }

    companion object {
        const val START = 0
        const val SUCCESS = 1
        const val FAIL = 2
        const val PROGRESS = 3

        fun  start(): TKState {
         return TKState(START)
        }

        fun  response(response: TKResponse?): TKState {
            if (response != null) {
            if (response.isSuccess()) {
                return TKState(SUCCESS, response.data, null)
            } else {
                return error(ServerException(response.code, response.msg))
            }

            } else {
            return error(NullResponseException(TKErrorCode.ERRCODE_RESPONSE_NULL, TKErrorCode.ERRCODE_RESPONSE_NULL_DESC))
            }

        }

        fun  error(t: Throwable?): TKState {
            return TKState(FAIL, t)
        }

        fun  progress(progress: Long, total: Long): TKState {
            return TKState(PROGRESS, progress, total)
        }
    }

}
 ```

 * 经过一系列封装,参考 demo 代码,最后在 View 层如 Activity 中 ViewModel 调用 Repository 中的接口
 ```kotlin
  viewModel.testPost(hashMapOf(
            "name" to "jack",
            "location" to "shanghai",
            "age" to 28)
    )
    .observeState(this) {
        onStart {
        LogUtils.d(TAG, "onButtonPost() onStart called")
        }
        onSuccess {
        LogUtils.d(TAG, "onButtonPost() onSuccess called:${it}")
        }
        onFailure { code, msg ->
        ToastHelper.toast("onButtonPost() onFailure,code:${code},msg:${msg}")
        }
        onComplete {
        LogUtils.d(TAG, "onButtonPost() onComplete called")
        }
    }
 ```

 **具体使用可以参考 demo 代码,demo 中有详细的示例演示 MVVM 项目如何使用 RxHttp**

强烈建议下载 Demo 代码,Demo 中有详细的示例,演示 MVVM 及 MVC 架构如何使用 RxHttp,如有问题可私信我,简书 掘金

License
Copyright (C) 2021 kongpf8848

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/878392.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号