一直是一个.NET开发工程师,最近想简单做个APP,遇到网络请求,发现很多人用的Retrofit2,定义了一大堆东西,我这个人喜欢简单的东西,而且我也不是专业做Android的,我就依葫芦画瓢,做了个类似axios结合Promise的功能,代码极少,喜欢的朋友,复制粘贴就能用
需要的依赖
implementation "com.squareup.okhttp3:okhttp:4.9.3"
implementation 'com.google.code.gson:gson:2.9.0'
以下是要用到的类和方法
TResult
package com.mqry.utility
class TResult<T> {
var IsSuccess: Boolean = true
var Code: Int = 10000
var Message: String = "操作成功"
var Description: String = ""
var Body: T? = null
}
JsonConvert
package com.mqry.utility
import android.util.Log
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import java.lang.reflect.Type
object JsonConvert {
fun Serialize(obj: Any): String {
return Gson().toJson(obj)
}
fun <T> Deserialize(json: String): T {
val type: Type =
object : TypeToken<T>() {}.type
var gson = Gson()
var result = gson.fromJson<T>(
json.toString(),
type
)
return result
}
inline fun <reified T> Any.ToArrayResult(): TResult<ArrayList<T>> {
return ToArrayResult(this.toString())
}
inline fun <reified T> ToArrayResult(json: String): TResult<ArrayList<T>> {
val type: Type =
object : TypeToken<TResult<ArrayList<T>>>() {}.type
var gson = Gson()
var result = gson.fromJson<TResult<ArrayList<T>>>(
json.toString(),
type
)
return result
}
inline fun <reified T> Any.ToObjectResult(): TResult<T> {
return ToObjectResult(this.toString())
}
inline fun <reified T> ToObjectResult(json: String): TResult<T> {
val type: Type =
object : TypeToken<TResult<T>>() {}.type
var gson = Gson()
var result = gson.fromJson<TResult<T>>(
json.toString(),
type
)
return result
}
}
Axios
package com.mqry.utility
import android.util.Log
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException
import java.util.*
class Axios() {
companion object {
lateinit var Instance: Axios
fun Init() {
Instance = AxiosBuilder()
.SetBaseUrl("设置成你要的URL,类似:https://www.baidu.com/")
.Build()
}
}
enum class AxiosMethod {
GET, POST
}
var BaseUrl: String = ""
var Headers: MutableMap<String, String> = mutableMapOf()
var ResponseString: String = ""
var onComplete: (responseBody: String) -> Promise = { responseBody ->
Promise.Resolve(responseBody)
}
fun Fetch(
method: AxiosMethod = AxiosMethod.POST,
url: String,
data: Any = "{}"
): Promise {
return Promise({ resolve, reject ->
val builder = Request.Builder()
.url(this.BaseUrl + url)
if (method == AxiosMethod.GET) {
builder.get()
}
if (method == AxiosMethod.POST) {
if (data is String) {
builder.post(data.toRequestBody("application/json;charset=utf-8".toMediaType()))
} else {
builder.post(
JsonConvert.Serialize(data)
.toRequestBody("application/json;charset=utf-8".toMediaType())
)
}
}
var request = builder.build()
val okHttpClient = OkHttpClient()
val call: Call = okHttpClient.newCall(request)
try {
var response = call.execute()
var responseString = response.body?.string().toString()
resolve(responseString)
} catch (e: Exception) {
reject(e.message)
}
})
}
}
class AxiosBuilder {
private lateinit var _axios: Axios
constructor() {
_axios = Axios()
}
fun SetBaseUrl(BaseUrl: String): AxiosBuilder {
_axios.BaseUrl = BaseUrl
return this
}
fun PutHeader(Key: String, Value: String): AxiosBuilder {
_axios.Headers.put(Key, Value)
return this
}
/**
* 我给你一个字符串,你自己处理成你要的Promise对象
*/
fun OnComplete(executer: (responseBody: String) -> Promise): AxiosBuilder {
_axios.onComplete = executer
return this
}
fun Build(): Axios {
return _axios
}
}
Promise
package com.mqry.utility
import kotlinx.coroutines.*
import java.lang.Exception
import java.lang.Runnable
class Promise() {
//region 状态枚举
enum class PROMISE_STATUS {
PENDING, RESOLVE, REJECT
}
//endregion
//region 属性
private var _status = PROMISE_STATUS.PENDING
private var _value: Any? = null
//未执行的Promise
private var _nextPromise: Promise? = null
private var _thisTimeOnResolve: ((Any?) -> Promise)? = null
private var _thisTimeOnReject: ((Any?) -> Unit)? = null
//endregion
//region 构造函数
constructor(executer: (resolve: (result: Any?) -> Unit, reject: (result: Any?) -> Unit) -> Unit) : this() {
var that = this
GlobalScope.launch() {
try {
executer(that::_resolve, that::_reject)
} catch (e: Exception) {
_reject(e.message.toString())
}
}
}
constructor(status: PROMISE_STATUS, value: Any? = null) : this() {
var that = this
that._status = status
that._value = value
}
//endregion
//region 处理函数
/**
* 成功处理
*/
private fun _resolve(result: Any? = null) {
this._value = result
this._status = PROMISE_STATUS.RESOLVE
//之前的then没有执行完成,手动执行一次
if (this._nextPromise != null && this._thisTimeOnResolve != null) {
var promise = try {
//结果他没执行完
_thisTimeOnResolve!!(this._value)
} catch (e: Exception) {
Promise.Reject(e.message.toString())
}
var maxCount = 0
//最好的办法,还是等待他处理完
while (promise._status == PROMISE_STATUS.PENDING) {
Thread.sleep(100)
maxCount++
if (maxCount > 1000) {//超过100秒算失败
promise._status = PROMISE_STATUS.REJECT
}
}
if (promise._status == PROMISE_STATUS.RESOLVE) {
this._nextPromise!!._resolve(promise._value)
}
if (promise._status == PROMISE_STATUS.REJECT) {
this._nextPromise!!._reject(promise._value)
}
}
}
/**
* 失败处理
*/
private fun _reject(result: Any? = null) {
this._value = result
this._status = PROMISE_STATUS.REJECT
if (_thisTimeOnReject == null) {
this._nextPromise?._reject(this._value)
} else {
_thisTimeOnReject!!(this._value)
}
}
//endregion
//region 核心方法
fun then(onResolve: (result: Any?) -> Promise): Promise {
//当下就成功了
if (_status == PROMISE_STATUS.RESOLVE) {
try {
return onResolve(_value)
} catch (e: Exception) {
return Promise.Reject(e.message.toString())
}
}
//当下就失败了
if (_status == PROMISE_STATUS.REJECT) {
return this
}
//未执行完成
if (_status == PROMISE_STATUS.PENDING) {
_thisTimeOnResolve = onResolve
_nextPromise = Promise()
return _nextPromise as Promise
}
throw Exception("未知错误!")
}
fun catch(onReject: (result: Any?) -> Unit) {
if (_status == PROMISE_STATUS.REJECT) {
onReject(_value)
}
//未执行完成
if (_status == PROMISE_STATUS.PENDING) {
_thisTimeOnReject = onReject
// _nextPromise = Promise()
}
}
//endregion
//region 静态方法
/**
* 静态方法
*/
companion object {
/**
* 成功处理
*/
fun Resolve(value: Any? = null): Promise {
return Promise(PROMISE_STATUS.RESOLVE, value)
}
/**
* 失败处理
*/
fun Reject(value: Any? = null): Promise {
return Promise(PROMISE_STATUS.REJECT, value)
}
}
//endregion
}
相关文章:
Android Kotlin 仿写 JS Promise 链式调用 支持异步
SaliyaService
把你的网络请求写进去
package com.mqry.api
import android.util.Log
import com.mqry.utility.Axios
import com.mqry.utility.Promise
object SaliyaService {
fun GetOrderFoodCount(Param: Saliya_GetOrderFoodCount_Param): Promise {
return Axios.Instance.Fetch(url = "/Saliya/GetOrderFoodCount", data = Param)
}
fun OrderFood(Param: Saliya_OrderFood_Param): Promise {
return Axios.Instance.Fetch(url = "/Saliya/OrderFood", data = Param)
}
fun ClearOrderFood(Param: Saliya_ClearOrderFood_Param): Promise {
return Axios.Instance.Fetch(url = "/Saliya/ClearOrderFood", data = Param)
}
fun GetOrderFoodList(Param: Saliya_GetOrderFoodList_Param): Promise {
return Axios.Instance.Fetch(url = "/Saliya/GetOrderFoodList", data = Param)
}
fun GetTypeList(Param: Saliya_GetTypeList_Param): Promise {
return Axios.Instance.Fetch(url = "/Saliya/GetTypeList", data = Param)
}
fun GetFoodList(Param: Saliya_GetFoodList_Param): Promise {
return Axios.Instance.Fetch(url = "/Saliya/GetFoodList", data = Param)
}
fun GetStoreList(Param: Saliya_GetStoreList_Param): Promise {
return Axios.Instance.Fetch(url = "/Saliya/GetStoreList", data = Param)
}
}
//region Param
data class Saliya_GetOrderFoodCount_Param(
var PK_StoreGuid: String = "",
var PK_FoodGuid: String = ""
)
data class Saliya_OrderFood_Param(
var PK_StoreGuid: String = "",
var PK_FoodGuid: String = "",
var Count: Int = 1,
var Direction: String = "1"
)
data class Saliya_ClearOrderFood_Param(
var PK_StoreGuid: String = ""
)
data class Saliya_GetOrderFoodList_Param(
var PK_StoreGuid: String = ""
)
class Saliya_GetTypeList_Param {
}
data class Saliya_GetFoodList_Param(
var PK_StoreGuid: String = "",
var TypeID: String = "",
var FoodName: String = ""
)
class Saliya_GetStoreList_Param {
}
//endregion
//region Result
class Saliya_GetOrderFoodCount_Result {
}
class Saliya_OrderFood_Result {
}
class Saliya_ClearOrderFood_Result {
}
class Saliya_GetOrderFoodList_Result {
var PK_OrderFoodGuid: String = ""
var PK_FoodGuid: String = ""
var PK_StoreGuid: String = ""
var FoodName: String = ""
var No: String = ""
var ImageUrl: String = ""
var Price: String = ""
var TotalPrice: Int = 0
var Count: String = ""
}
class Saliya_GetTypeList_Result {
var TypeID: String = ""
var TypeName: String = ""
}
class Saliya_GetFoodList_Result {
var PK_FoodGuid: String = ""
var FK_StoreGuid: String = ""
var ImageUrl: String = ""
var FoodName: String = ""
var Description: String = ""
var Price: String = ""
var TypeID: String = ""
var No: String = ""
}
class Saliya_GetStoreList_Result {
var PK_StoreGuid: String = ""
var StoreName: String = ""
var Address: String = ""
var Telephone: String = ""
var SaleTime: String = ""
}
//endregion
再找个地方初始化一下Axios
package com.mqry
import android.app.Application
import android.util.Log
import com.mqry.utility.Axios
import com.mqry.utility.AxiosBuilder
class AppLauncher : Application() {
override fun onCreate() {
super.onCreate()
Axios.Init()
}
}
设置下启动器
![](https://img.haomeiwen.com/i13488542/83b2db78c55d982e.png)
调用示例
package com.mqry
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import com.mqry.api.SaliyaService
import com.mqry.api.Saliya_GetFoodList_Param
import com.mqry.api.Saliya_GetFoodList_Result
import com.mqry.api.Saliya_GetOrderFoodCount_Param
import com.mqry.utility.JsonConvert.ToArrayResult
import com.mqry.utility.JsonConvert.ToObjectResult
import com.mqry.utility.Promise
import com.mqry.utility.TResult
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
SaliyaService.GetOrderFoodCount(
Saliya_GetOrderFoodCount_Param(
PK_StoreGuid = "C3358DD8-093C-4377-BDE9-06818D6588AB",
PK_FoodGuid = "5D5C0772-E44B-4DCF-89D9-204E8F867168"
)
).then { r ->
Log.i("XX","GetFoodList")
//这一步的结果集
var rr: TResult<Int> = r!!.ToObjectResult<Int>()
//连调
SaliyaService.GetFoodList(
Saliya_GetFoodList_Param(
PK_StoreGuid = "C3358DD8-093C-4377-BDE9-06818D6588AB",
TypeID = "",
FoodName = ""
)
)
}.then { r ->
Log.i("XX","GetOrderFoodCount")
var rr= r!!.ToArrayResult<Saliya_GetFoodList_Result>()
Promise.Resolve()
}.catch { r ->
}
}
}
↑↑↑以上就是模仿JS Axios Promise对象的网络请求,懂的朋友可以自行修改和复制粘贴↑↑↑
网友评论