Harmony os Next——Retrofit网络库的使用和封装

这里写目录标题

Harmony os Next------Retrofit网络库的使用和封装

描述

Retrofit作为Android平台最为常用的一个第三方网络库,搭配Kotlin的协程,使用极为便捷。通过Harmony的工作人员的努力,制作出的Retrofit For Harmony Library依旧十分强大。

通过在oh-package.json5文件中添加如下依赖即可完成装配,具体版本可以查看retrofit api

"@ohos/retrofit": "2.0.1-rc.0"

同时也可以通过添加httpclient为其添加拦截器等

"@ohos/httpclient": "2.0.0-rc.9",

Retrofit的使用

BaseService

需要创建一个类继承BaseService。同时可以在类名上方加一个@BasePath("/")注解。

意味在BaseUrl后面补全一个/。因为在后面通过ServiceBuilder创建AppService实例时,需要指定BaseUrl,例如BaseUrlhttps://api.xxxx.com,在类上面添加注解@BasePath("/"),便会自动在BaseUrl后面加一个/,后面的具体接口就不需要加/,例如有一个获取天气的子接口api/weather,最终拼凑的就是https://api.xxxx.com/api/weather

c 复制代码
@BasePath("/")
class AppService extends BaseService{
}

部分功能使用

GET

其中NetworkConstants.GET_WEATHER就是上述举例的api/weather,在其前面使用GET注解进行包裹,然后可以通过@Query传递参数。最后返回的数据是通过异步的方式返回。Promise<Response<...>>为固定返回参数,BaseModel<WeatherModel>为api接口返回的JSON数据格式,可根据项目自行定义

c 复制代码
@BasePath("/")
class AppService extends BaseService{
 @GET(NetworkConstants.GET_WEATHER)
  async getWeather(
    @Query("cityId") cityId: string
  ): Promise<Response<BaseModel<WeatherModel>>> { return {} as Response<BaseModel<WeatherModel>> }
}

POST

GET使用一致,通过POST注解进行包裹,同样可以使用@Field进行参数传递,其中 @FormUrlEncoded注解是给此方法添加如下参数头

'content-type': 'application/x-www-form-urlencoded;charset=utf-8'

c 复制代码
@BasePath("/")
class AppService extends BaseService{
  @FormUrlEncoded
  @POST(NetworkConstants.TEST_API)
  async postTestApi(
    @Field("testId")testId : string
  ): Promise<Response<BaseModel<TestModel>>> { return {} as Response<BaseModel<TestModel>> }
}

创建拦截器

以打印日子拦截器为例,可以将每一个API请求的方法、参数、URL、返回结果等进行打印输出,便于测试。具体如下

c 复制代码
class LoggingInterceptor implements Interceptor{
  async intercept(chain: Chain): Promise<Response> {
    try {
      let request = chain.requestI()
      let requestBody: RequestBody = request.body
      let url = request.url as HttpUrl
      const connectResponse = await chain.proceedI(chain.requestI())
      let startMessage = `-->${request.method} ${url.url} ${connectResponse.protocol ?? ''}`
      let contentType: string = requestBody.content
      let endMessage = `--> END ${request.method}`
      Logger.info(`Headers:${JSON.stringify(request.headers)}`)
      Logger.info(startMessage)
      Logger.info(contentType)
      Logger.info(endMessage)
      return connectResponse
    } catch (error) {
      return new Promise<Response>((resolve, reject) => {
        let request = chain.requestI()
        let response = chain.proceedI(request)
        response.then((data) => {
          resolve(data)
        }).catch((err: Error) => {
          reject(err)
        });
      })
    }
  }
}

创建实例

通过addInterceptor便可以添加上述我们创建的日志打印拦截器

通过setEndpoint可以设置BASEURL

通过在build函数里面指定需要创建的BaseService子类

c 复制代码
let client: HttpClient = new  HttpClient.Builder()
  .setConnectTimeout(5, TimeUnit.SECONDS)
  .setReadTimeout(5, TimeUnit.SECONDS)
  .addInterceptor(loggingInterceptor)
  .build()

export const appService = new ServiceBuilder()
  .setEndpoint(NetworkConstants.BASEURL)
  .setClient(client)
  .build(AppService)

全局封装

通过创建一个全局范型方法baseApiRequest,将api请求的异常进行集中处理,只对其成功返回的结果和错误进行返回,可以避免重复异常处理

c 复制代码
export function baseApiRequest<T>(
    apiCall: Promise<Response<T>>,
    onSuccess: (result: T) => void,
    onFailed: (error: ResourceStr) => void
) {
  apiCall.then((result: Response<T>) => {
    if (result.isSuccessful() && result.code() == HttpStatusCode.SUCCESS) {
      onSuccess(result.result)
    } else {
      onFailed(result.message())
    }
  }).catch((error: Error) => {
    if (error as IOException) {
      //网络错误
      onFailed($r('app.string.HH_Public_DisconnectNetwork'))
    }else {
      onFailed(error.message)
    }
  })
}

具体使用如下所示,就此我们就可以将一个网络请求接口简化到下面方法一样

c 复制代码
baseApiRequest(
      appService.getWeather(citeId),
      (result) => {
        if (result.code === HttpStatusCode.SUCCESS) {
         //successful
        } else {
        //failed-error code
          promptAction.showToast({ message: result.message })
        }
      },
      (error) => {
      //failed
        Logger.info(`${error}`)
        promptAction.showToast({ message: error })
      }
    )
相关推荐
CYY952 天前
OkHttp 和 Retrofit 封装使用
okhttp·retrofit
CYY955 天前
Retrofit 的使用
retrofit
两个人的幸福10 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820713 天前
PHP 扩展——从入门到理解
php
鹏仔先生14 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
网络研究院14 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智14 天前
ARP代理--工作原理
运维·网络·arp·arp代理
云水一下14 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php