• 鸿蒙开发HarmonyOS Next 网络框架retrofit 封装 viemodel使用


    新手刚开始学习harmonyos开发,之前搞安卓开发习惯使用retrofit,结果在三方库中还真搜到了,然后就模拟学习一下。有不对的地方请指点一下。新手新手

    oh-package.json5 引入库

    retofit 需要使用2.0.1-rc.0 以上版本,修复了retrofit发送网络请求,响应结果未正常解析的问题。

    1. "@ohos/retrofit": "2.0.1-rc.0",
    2. "@ohos/httpclient": "2.0.1-rc.5",

    页面使用

    1. @Entry
    2. @Component
    3. struct LoginPage {
    4. @State viewModel: LoginViewModel = new LoginViewModel()
    5. .....省略
    6. Button("登录")
    7. .width("85%")
    8. .height(50)
    9. .margin({ top: 65 })
    10. .onClick(() => {
    11. if (StrUtil.isEmpty(this.viewModel.userName)) {
    12. ToastUtil.showToast("请输入用户名")
    13. return
    14. }
    15. if (StrUtil.isEmpty(this.viewModel.password)) {
    16. ToastUtil.showToast("请输入密码")
    17. return
    18. }
    19. this.viewModel.getToken()
    20. })
    21. }

    viewmodel使用

    1. @Observed
    2. export class LoginViewModel {
    3. userName: string = ""
    4. password: string = ""
    5. .....省略
    6. getToken() {
    7. let params = new Map<string, undefined>()
    8. params["username"] = this.userName
    9. params["password"] = this.password
    10. baseApiRequest<Token>(
    11. appService.getToken(params),
    12. (result) => {
    13. Logger.debug("" + result.accessToken)
    14. },
    15. //可选参数,可不传
    16. {
    17. onFailed: (error) => {
    18. }, showLoading: true, loadingStr: "zzzzzzz"
    19. }
    20. )
    21. }
    22. }

    定义接口

    @BasePath("/")
    export class AppService extends BaseService {
    
      @GET("szy/uaa/oauth/token")
      async getToken(@QueryMap params: Map): Promise>> {
        return {} as Response>
      }
    }
    

    httpclient 拦截器

    1. export class LoggingInterceptor implements Interceptor {
    2. async intercept(chain: Chain): Promise<Response> {
    3. try {
    4. let request = chain.requestI()
    5. let requestBody: RequestBody = request.body
    6. let url = request.url as HttpUrl
    7. const connectResponse = await chain.proceedI(chain.requestI())
    8. let startMessage = `-->${request.method} ${url.url} ${connectResponse.protocol ?? ''}`
    9. let contentType: string = requestBody.content
    10. let endMessage = `--> END ${request.method}`
    11. LoggerUtils.debug("添加日志拦截器")
    12. LoggerUtils.debug(`Headers:${JSON.stringify(request.headers)}`)
    13. LoggerUtils.debug("httpStart = " + startMessage)
    14. LoggerUtils.debug("contentType = " + contentType)
    15. LoggerUtils.debug("Response = " + connectResponse.result)
    16. LoggerUtils.debug("httpEnd = " + endMessage)
    17. return connectResponse
    18. } catch (error) {
    19. LoggerUtils.debug("添加日志拦截器 失败")
    20. return new Promise<Response>((resolve, reject) => {
    21. let request = chain.requestI()
    22. let response = chain.proceedI(request)
    23. response.then((data) => {
    24. resolve(data)
    25. }).catch((err: Error) => {
    26. reject(err)
    27. });
    28. })
    29. }
    30. }
    31. }

    RetrofitApi.ets简单封装

    1. import { HttpClient, IOException, TimeUnit } from '@ohos/httpclient'
    2. import { Response, ServiceBuilder } from '@ohos/retrofit'
    3. import { ToastUtil } from '@pura/harmony-utils'
    4. import { NetworkConstants } from '../../common/NetworkConstants'
    5. import { ApiResponse } from './ApiResponse'
    6. import { AppService } from './AppService'
    7. import { HeaderInterceptor } from './HeaderInterceptor'
    8. import { LoggingInterceptor } from './LoggingInterceptor'
    9. import { DialogUtils } from '../../common/DialogUtils'
    10. let client: HttpClient = new HttpClient.Builder()
    11. .setConnectTimeout(15, TimeUnit.SECONDS)
    12. .setReadTimeout(15, TimeUnit.SECONDS)
    13. .addInterceptor(new LoggingInterceptor())
    14. .addInterceptor(new HeaderInterceptor())
    15. .build()
    16. export const appService = new ServiceBuilder()
    17. .setEndpoint(NetworkConstants.BASE_URL)
    18. .setClient(client)
    19. .build(AppService)
    20. /**
    21. * 可选参数
    22. */
    23. interface ApiParams {
    24. onFailed?: (error: ResourceStr) => void,
    25. showLoading?: boolean,
    26. loadingStr?: string
    27. }
    28. export function baseApiRequest<T>(
    29. apiCall: Promise<Response<ApiResponse<T>>>,
    30. onSuccess: (result: T) => void,
    31. param?: ApiParams,
    32. ) {
    33. if (param?.showLoading) {
    34. DialogUtils.showLoading(param.loadingStr)
    35. }
    36. apiCall.then((result: Response<ApiResponse<T>>) => {
    37. if (result.isSuccessful() && result.code() == 200 && result.result.success) {
    38. onSuccess(result.result.data)
    39. } else {
    40. ToastUtil.showToast(result.result.message)
    41. if (param?.onFailed) {
    42. param.onFailed(result.result.message)
    43. }
    44. }
    45. DialogUtils.dismiss()
    46. }).catch((error: Error) => {
    47. if (error as IOException) {
    48. if (param?.onFailed) {
    49. param.onFailed('error = ' + error)
    50. }
    51. } else {
    52. if (param?.onFailed) {
    53. param.onFailed(error.message)
    54. }
    55. }
    56. ToastUtil.showToast(error.message)
    57. DialogUtils.dismiss()
    58. })
    59. }

  • 相关阅读:
    冲刺学习-MySQL-基础
    为了方便,采用数据库连接池druid
    含文档+PPT+源码等]精品基于Uniapp实现的美食APP[包运行成功]计算机毕业设计安卓项目源码
    UE学习记录07----C++中使用事件委托
    WebService SOAP1.1 SOAP1.12 HTTP PSOT方式调用
    Java—泛型、内部类、多继承
    mysql中binlog日志
    ReLabel:自动将ImageNet转化成多标签数据集,更准确地有监督训练 | 2021新文
    【深度学习】U-net网络结构搭建 | pytorch
    【面经】讲一下BASE理论
  • 原文地址:https://blog.csdn.net/mengshirui_/article/details/139605422