写点什么

鸿蒙实战开发:网络层的艺术——优雅封装与搭建指南(下)

  • 2024-11-04
    北京
  • 本文字数:2562 字

    阅读完需:约 8 分钟

前言

在前两篇文章中,我们深入探讨了网络层的封装和优化技巧。本文将带您走进网络层的实战应用,从架构设计到具体实现,一步步指导您如何使用我们精心构建的网络框架。

一、网络层架构设计

在鸿蒙应用开发中,一个清晰、合理的网络层架构是保证项目可维护性和扩展性的关键。以下是我们推荐的网络层目录结构:


项目|-- network    |-- data        |-- models            |-- params            // 请求模型            |-- responses         // 返回模型        |-- service             // 网络接口定义        |-- sources            |-- remote            // 网络数据源
复制代码

二、Service 网络接口设计与实现

1. 构建网络接口

接口常量文件ApiMethod.ets,用于集中管理所有网络请求的路径。


// 接口请求路径常量定义,便于统一管理和引用const HARMONY_INDEX = "harmony/index/json";export { HARMONY_INDEX };
复制代码

2. 网络请求类

ApiRequest类作为网络请求的中心,负责网络库的初始化、配置以及请求的调用和拼装。


type DataClassConstructor<T> = ClassConstructor<ApiResult<T>>;export class ApiRequest{
private static instance: ApiRequest

static getInstance (): ApiRequest { if (!ApiRequest.instance) { ApiRequest.instance = new ApiRequest() } return ApiRequest.instance }
net : NetworkService
constructor() { this.net = new NetworkService("https://www.wanandroid.com/"); this.net.dataConverter = new JsonDataConverter() this.net.addInterceptor(new DefaultInterceptor()) }
public getService() : NetworkService{ return this.net; }
private plainToClassApiResult<T>(ctor: DataClassConstructor<T>, data: object) : ApiResult<T>{ return plainToClass(ctor,data,{ enableImplicitConversion: false, exposeDefaultValues: true,}) as ApiResult<T>; } async requestHarmonyIndex(harmonyIndex: HarmonyIndexParam): Promise<ApiResult<HarmonyIndexResponse>> { let data = await ApiRequest.getInstance().getService().request({ act : HARMONY_INDEX, expectDataType : http.HttpDataType.OBJECT, queryParams : new Map(Object.entries(harmonyIndex)), method: RequestMethod.GET }) let result :ApiResult<HarmonyIndexResponse> = this.plainToClassApiResult<HarmonyIndexResponse>( ApiResult , data.result as object,) return result; }

}
复制代码

三、网络数据源层

1. 网络数据源

BaseRemoteSource类提供了基础的网络请求处理,包括显示加载弹窗和基本的错误处理。


// BaseRemoteSource 类实现基础网络请求和错误处理class BaseRemoteSource {  async baseRequest<T>(request: Promise<ApiResult<T>>, option?: DataSourceOption): Promise<DataResult<ApiResult<T>>> {    try {      // 显示加载提示      NetworkUtil.showSpinner(option);      const result = await request;      // 隐藏加载提示      NetworkUtil.hideSpinner(option);      // 根据结果进行相应处理      return result.errorCode === 0        ? new SuccessData(result)        : new ErrorData(new AppBusinessError(result.errorCode!, result.errorMsg!));    } catch (e) {      // 异常处理      const error = e as BaseError;      NetworkUtil.hideSpinner(option);      if (option?.showErrorTips) {        LibToast.show(error.message);      }      return new ErrorData(e);    }  }}
复制代码

2. 网络数据源实现类

WanRemoteSource类继承自BaseRemoteSource,实现了具体的网络请求。


// WanRemoteSource 类实现特定业务的网络请求class WanRemoteSource extends BaseRemoteSource {  async requestHarmonyIndex(harmonyIndex: HarmonyIndexParam): Promise<DataResult<ApiResult<HarmonyIndexResponse>>> {    const option = new DataSourceOption();    option.showSpinner = true;    return this.baseRequest(ApiRequest.getInstance().requestHarmonyIndex(harmonyIndex), option);  }}
复制代码

3. 数据仓库

WanResponsitory类作为数据仓库,负责协调远程数据源和可能的本地数据源。


// WanResponsitory 类实现数据仓库模式class WanResponsitory implements IWanSource {  private static instance: WanResponsitory;  private remoteSource: IWanSource;
private constructor() { this.remoteSource = new WanRemoteSource(); // ...(省略部分代码) }
public static getInstance(): WanResponsitory { if (!WanResponsitory.instance) { WanResponsitory.instance = new WanResponsitory(); } return WanResponsitory.instance; }
requestHarmonyIndex(harmonyIndex: HarmonyIndexParam): Promise<DataResult<ApiResult<HarmonyIndexResponse>>> { return this.remoteSource.requestHarmonyIndex(harmonyIndex); }}
复制代码

四、页面业务端使用

在页面业务逻辑中,我们通过调用数据仓库的方法来执行网络请求,并处理返回结果。


// 页面中按钮点击事件的处理Button('网络请求')  .attributeModifier(new ColumnButtonStyle)  .onClick(() => {    WanResponsitory.getInstance().requestHarmonyIndex(new HarmonyIndexParam()).then((value) => {      if (value instanceof SuccessData) {        const data = value as SuccessData<ApiResult<HarmonyIndexResponse>>;        LibToast.show(`展示:${data.data?.data?.links?.name}`);      } else if (value instanceof ErrorData) {        const error = value.error;        if (error instanceof AppBusinessError) {          LibToast.show(`业务异常:${error.code}`);        }      }    });  });
复制代码

结语

本文详细介绍了如何使用我们编写的网络框架,从架构设计到具体实现,每一步都体现了对高效、可维护代码的追求。希望这些知识能够帮助您在鸿蒙开发中更加得心应手,构建出更加健壮和用户友好的应用。

发布于: 刚刚阅读数: 5
用户头像

还未添加个人签名 2021-11-19 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙实战开发:网络层的艺术——优雅封装与搭建指南(下)_鸿蒙_王二蛋和他的张大花_InfoQ写作社区