当前位置: 首页 > 工具软件 > FUEL > 使用案例 >

Android kotlin网络请求框架fuel(简单方便的使用,提供项目中使用实例)

宣原
2023-12-01

不知道Fuel的朋友可以看下下面这几篇文章,这里主要讲项目中的使用流程

GitHub地址

Kotlin网络库Fuel的设计之道

Kotlin实战之Fuel的高阶函数

接入AS:


    //fuel框架
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
    implementation "com.github.kittinunf.fuel:fuel-rxjava:$fuel_version"
    implementation "com.github.kittinunf.fuel:fuel-android:$fuel_version"
    implementation "com.github.kittinunf.fuel:fuel-livedata:$fuel_version"
    implementation "com.github.kittinunf.fuel:fuel-gson:$fuel_version"

初始化,添加拦截器

import com.github.kittinunf.fuel.core.FuelManager
import com.github.kittinunf.fuel.core.Method
import com.github.kittinunf.fuel.core.Request
import com.sg.dpraise.BuildConfig
import com.sg.dpraise.common.utils.log

/**
 * Author:xqt
 * Date: 2018/12/21
 * Description:初始化fuel网络请求
 */
object FuelTestHelper{
    fun initFuel(){
        //val requestInterceptors: MutableList<((Request)-> Request)-> ((Request)->Request)> = mutableListOf()
        //服务器接口地址
        FuelManager.instance.basePath = "http://www.xxxxxx.com"
        //超时时间20秒
        FuelManager.instance.timeoutInMillisecond = 20000
        //FuelManager.instance.baseHeaders = mapOf("token" to "BearerAbCdEf123456")
        //添加header拦截器
        FuelManager.instance.addRequestInterceptor(tokenInterceptor())
        //添加请求日志拦截器
        FuelManager.instance.addRequestInterceptor(cUrlLoggingRequestInterceptor())
        //foldRight 是 List 的一个扩展函数 从右往左,对列表中的每一个元素执行 operation 操作,
        // 每个操作的结果是下一次操作的入参,第一次 operation 的初始值是 initial。
        //requestInterceptors.foldRight({r: Request -> r}){f,acc-> f(acc)}
    }
    /**
    * @Author :xqt
    * @Description :日志拦截器
    * @Return :
    * @Params :
    */
    private fun cUrlLoggingRequestInterceptor() ={
        next: (Request) -> Request ->{
            r: Request ->
                    var logging = StringBuffer()
                    logging.append("\n-----Method = ${r.method}")
                    logging.append("\n-----mediaTypes = ${r.mediaTypes}")
                    logging.append("\n-----headers = ${r.headers}")
                    logging.append("\n-----url---->${r.url}")
                    when(r.method){
                        Method.POST->{
                            logging.append("\n-----request parameters:")
                            r.parameters.forEach {
                                logging.append("\n-----${it.first}=${it.second}")
                            }
                        }
                    }
                    log(logging)
                    next(r)
                }
            }

    /**
    * @Author :xqt
    * @Description :添加header
    * @Return :
    * @Params :
    */
    private fun tokenInterceptor() = {
        next: (Request) -> Request ->{
            req: Request ->
                //"Content-Type:application/x-www-form-urlencoded; charset=UTF-8"
                req.header(mapOf("token" to "BearerAbCdEf123456"))//变量替换
                next(req)
        }
    }
}

在application中或者主activity中调用FuelTestHelper.initFuel()方法做初始操作

下面定义所有请求的公共方法:(注:demo里面这里有误,无法解析,请按照下面的代码修改)

-----------------以下需求手动修改--------------------------------

fun <T> Request.request(context: Context,helper: HttpHelper<T>,dialogTip:String? = null){
    var dialog = context.createLoadingDialog(dialogTip)
    this.rx_responseString()
           .subscribeOn(Schedulers.io())
           .observeOn(AndroidSchedulers.mainThread())
           .subscribe{result->
               dialog?.stopLoadingDialog()
               val (_, rt) = result
               val err = rt.component2()
               if (err == null) {//请求成功
                   log(rt.component1())
                   var resp = Gson().fromJson<Resp>(rt.component1(), Resp::class.java)
                   when(resp?.code){
                       0-> {
                           var data = Gson().fromJson<T>(resp.data, helper.rawType)
                           helper.onReqFinish(data, 0)
                       }
                       else-> {
                           toast(resp.msg)
                           helper.onReqFinish(null, -1)
                       }
                   }

               } else {//请求失败
                   helper.onReqFinish(null,-1)
                   log(err.toString())
                   var msg = Error.REQUEST_ERROR
                   when(err.exception){
                       is JsonSyntaxException -> msg = Error.PARSER_ERROR
                       is ConnectException -> msg = Error.NET_ERROR
                       is SocketTimeoutException -> msg = Error.NET_TIMEOUT_ERROR
                       is HttpException -> msg = Error.SERVER_ERROR
                       is UnknownHostException -> msg = Error.NET_ERROR
                   }
                   toast(msg)
               }
           }
}
/**
* @Author :xqt
* @Description :创建对话框
* @Return :
* @Params :
*/
fun Context.createLoadingDialog(msg:String? = null):LoadingDialog? {
    var loadingDialog = LoadingDialog(this, R.style.loadingdialog)//创建Dialog并设置样式主题
    loadingDialog?.setCancelable(false)
    loadingDialog?.show()
    if (msg != null){
        loadingDialog?.setLoadMsg(msg)
    }
    return loadingDialog
}

/**
* @Author :xqt
* @Description :关闭
* @Return :
* @Params :
*/
fun LoadingDialog?.stopLoadingDialog() {
    if (this!=null && this?.isShowing){
        this?.dismiss()
    }
}

HttpHelper方便回调可自行定义:

/**
 * 请求回调
 */
abstract class HttpHelper<T> {
    abstract fun onReqFinish(data: T?, code: Int)
    /**
    * @Author :xqt
    * @Description :延迟初始化
    */
    val rawType: Type by lazy {
        getSuperclassTypeParameter(javaClass)
    }

    companion object {
        fun getSuperclassTypeParameter(cls:Class<*>): Type {
            val superclass = cls.genericSuperclass
            if (superclass is Class<*>) {
                throw RuntimeException("Missing type parameter.")
            }
            val parameterized = superclass as ParameterizedType
            return `$Gson$Types`.canonicalize(parameterized.actualTypeArguments[0])
        }
    }

}

Resp数据解析类:

/**
 * 基础返回数据结构
 */
data class Resp<T> (
        var code:Int = -10000,
        var data: T? = null,
        var msg: String? = null
)

-----------------以上需求手动修改--------------------------------

实际调用:


import android.view.View
import com.github.kittinunf.fuel.httpGet
import com.sg.dpraise.R
import com.sg.dpraise.bean.frame.UserModel
import com.sg.dpraise.common.utils.isMyEmpty
import com.sg.dpraise.common.utils.setStatusColor
import com.sg.dpraise.common.utils.toast
import com.sg.dpraise.frame.base.BaseFragmentActivity
import com.sg.dpraise.http.ApiConstant
import com.sg.dpraise.http.HttpHelper
import com.sg.dpraise.http.request
import kotlinx.android.synthetic.main.activity_login_layout.*
import org.jetbrains.anko.startActivity

/**
 * Author:xqt
 * Date: 2018/12/27
 * Description:
 */
class LoginActivity : BaseFragmentActivity() {
    override fun getLayoutResId() = R.layout.activity_login_layout
    /**
    * @Description :初始化操作
    */
    override fun initView() {
    }
    /**
    * @Description :initView调用完成后调用 做数据初始操作
    */
    override fun initData() {
    }

    fun onClick(v: View){
        when(v.id){
            R.id.R_tvLogin -> login()
            R.id.R_tvForgotPwd -> forgotPwd()
            R.id.R_tvRegister -> register()
        }
    }
    /**
    * @Description :注册
    */
    private fun register() {
        startActivity<RegisterActivity>()
    }

    /**
     * @Description :忘记密码
     */
    private fun forgotPwd() {
        startActivity<ForgotPwdActivity>()
    }

    /**
     * @Description :登录
     */
    private fun login() {
        var phone = R_editPhone.text.toString()
        var pwd = R_editPwd.text.toString()
        when {
            phone.isMyEmpty() -> {
                toast("手机号不能为空")
                return
            }
            pwd.isMyEmpty() -> {
                toast("密码不能为空")
                return
            }
            pwd.length < 6 -> {
                toast("密码不能小于6位")
                return
            }
            else -> {
                //登录
                ApiConstant.LOGIN_API.httpGet(listOf("phone" to phone,"password" to pwd))
                        .request(this,object: HttpHelper<UserModel> {
                            override fun onReqFinish(data: UserModel?, code: Int) {
                                //处理结果
                                if (code == 0){
                                    //登录成功
                                }
                            }
                        })
//                ApiConstant.LOGIN_API.httpPost(listOf("phone" to phone,"password" to pwd))
//                        .request(this,object: HttpHelper<List<UserModel>> {
//                            override fun onReqFinish(data: List<UserModel>?, code: Int) {
//                                //处理结果
//                                if (code == 0){
//                                    //登录成功
//                                }
//                            }
//                        })
            }
        }
    }
}

这里使用接口地址直接调用的方式(ApiConstant.LOGIN_API)

object ApiConstant {
   const val LOGIN_API = "/api/shop/login"
   const val FORGOT_PWD_API = "/api/shop/forgetPwd"
}

 

demo下载

 

 类似资料: