EntryAbility 全局初始化 + 网络请求 HttpUtil 完整源码

一、EntryAbility 全局统一初始化(项目启动唯一入口)

ets

复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import GlobalStore from '@ohos:har_base/utils/store';
import FileUtil from '@ohos:har_base/utils/file_util';
import LogUtil, { LogLevel } from '@ohos:har_base/utils/log_util';
import HttpUtil from '@ohos:har_base/utils/http_util';

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    hilog.info(0x0001, "APP_LIFE", "应用启动 onCreate");
    const context = this.context;

    // 1. 给所有底层工具注入上下文
    FileUtil.setContext(context);
    LogUtil.setContext(context);
    GlobalStore.setContext(context);

    // 2. 生产环境关闭调试日志
    LogUtil.setLogLevel(LogLevel.INFO);

    // 3. 初始化持久化全局状态
    GlobalStore.initPersistent();

    // 4. 初始化网络全局配置(基础域名、超时时间)
    HttpUtil.initBaseConfig({
      baseUrl: "https://api.test.com",
      timeout: 10000
    });

    LogUtil.info("EntryAbility", "全局工具初始化完成");
  }

  onForeground() {
    LogUtil.info("APP_LIFE", "应用切前台");
  }

  onBackground() {
    LogUtil.info("APP_LIFE", "应用切后台,中断所有未完成网络请求");
    HttpUtil.abortAllRequest();
  }

  onDestroy() {
    LogUtil.info("APP_LIFE", "应用销毁,释放全部资源");
  }
}

二、HttpUtil 网络请求封装(har_base 核心工具)

ets

复制代码
import http from '@ohos.net.http';
import LogUtil from './log_util';
import GlobalStore from './store';
import DialogUtil from './dialog_util';

// 全局网络基础配置
interface HttpBaseConfig {
  baseUrl: string;
  timeout: number;
}

// 通用响应结构
interface HttpResponse<T> {
  code: number;
  msg: string;
  data: T;
}

class HttpUtil {
  private baseConfig: HttpBaseConfig = {
    baseUrl: "",
    timeout: 10000
  };
  // 保存所有请求任务,页面销毁统一中断
  private requestTaskList: http.HttpRequest[] = [];

  initBaseConfig(config: HttpBaseConfig) {
    this.baseConfig = config;
  }

  // 生成统一请求头,自动携带token
  private getCommonHeader(): Record<string, string> {
    const token = GlobalStore.get<string>("token");
    return {
      "Content-Type": "application/json;charset=utf-8",
      "token": token
    };
  }

  // 中断全部网络请求
  abortAllRequest() {
    this.requestTaskList.forEach(task => {
      try {
        task.destroy();
      } catch (e) {
        LogUtil.warn("HttpUtil", "请求销毁异常", e);
      }
    });
    this.requestTaskList = [];
  }

  // 统一请求核心方法
  private async request<T>(
    url: string,
    method: http.RequestMethod,
    data?: Object
  ): Promise<HttpResponse<T> | null> {
    // 拼接完整接口地址
    let fullUrl = url.startsWith("http") ? url : `${this.baseConfig.baseUrl}${url}`;
    const httpRequest = http.createHttp();
    this.requestTaskList.push(httpRequest);

    try {
      DialogUtil.showLoading();
      LogUtil.debug("HttpUtil", `发起${method}请求:`, fullUrl, data);

      const res = await httpRequest.request(fullUrl, {
        method: method,
        header: this.getCommonHeader(),
        extraData: data ? JSON.stringify(data) : undefined,
        connectTimeout: this.baseConfig.timeout,
        readTimeout: this.baseConfig.timeout
      });

      DialogUtil.hideLoading();
      const result = JSON.parse(res.result.toString()) as HttpResponse<T>;
      LogUtil.debug("HttpUtil", "接口返回数据", result);

      // 登录失效,清空登录状态跳转登录页
      if (result.code === 401) {
        LogUtil.warn("HttpUtil", "token失效,退出登录");
        GlobalStore.logout();
        DialogUtil.alert({ content: "登录已过期,请重新登录" });
      }
      return result;
    } catch (err) {
      DialogUtil.hideLoading();
      LogUtil.error("HttpUtil", "网络请求异常", err);
      DialogUtil.alert({ content: "网络请求失败,请检查网络" });
      return null;
    }
  }

  // GET 请求
  get<T>(url: string, params?: Object): Promise<HttpResponse<T> | null> {
    return this.request<T>(url, http.RequestMethod.GET, params);
  }

  // POST 请求
  post<T>(url: string, data?: Object): Promise<HttpResponse<T> | null> {
    return this.request<T>(url, http.RequestMethod.POST, data);
  }
}

export default new HttpUtil();

三、全局弹窗工具 DialogUtil(har_base 配套工具)

ets

复制代码
import customDialog from '@ohos.arkui.component.customDialog';
import LogUtil from './log_util';

// 弹窗基础参数
interface AlertOpt {
  content: string;
  confirmText?: string;
  cancelText?: string;
  onConfirm?: () => void;
  onCancel?: () => void;
}

class DialogUtil {
  private dialogControllerList: customDialog.CustomDialogController[] = [];

  // 普通提示弹窗(仅确认按钮)
  alert(opt: AlertOpt) {
    const controller = customDialog.show({
      builder: () => {
        Column({ space: 16 }) {
          Text(opt.content).fontSize(16).textAlign(TextAlign.Center)
          Button(opt.confirmText ?? "确定")
            .width("100%")
            .height(44)
            .onClick(() => {
              controller.close();
              opt.onConfirm?.();
            })
        }
        .width("90%")
        .padding(20)
        .borderRadius(12)
      }
    });
    this.dialogControllerList.push(controller);
  }

  // 确认弹窗(确认+取消)
  confirm(opt: AlertOpt) {
    const controller = customDialog.show({
      builder: () => {
        Column({ space: 16 }) {
          Text(opt.content).fontSize(16).textAlign(TextAlign.Center)
          Row({ space: 12 }) {
            Button(opt.cancelText ?? "取消")
              .layoutWeight(1)
              .backgroundColor("#cccccc")
              .onClick(() => {
                controller.close();
                opt.onCancel?.();
              })
            Button(opt.confirmText ?? "确认")
              .layoutWeight(1)
              .backgroundColor("#007DFF")
              .onClick(() => {
                controller.close();
                opt.onConfirm?.();
              })
          }
        }
        .width("90%")
        .padding(20)
        .borderRadius(12)
      }
    });
    this.dialogControllerList.push(controller);
  }

  // 全局加载弹窗
  showLoading() {
    const controller = customDialog.show({
      builder: () => {
        Column({ space: 12 }) {
          Text("⟳").fontSize(32)
          Text("加载中...").fontSize(14)
        }
        .width(120)
        .height(120)
        .borderRadius(12)
        .backgroundColor("#ffffff")
      },
      mask: true
    });
    this.dialogControllerList.push(controller);
  }

  hideLoading() {
    if (this.dialogControllerList.length > 0) {
      const last = this.dialogControllerList.pop();
      last?.close();
    }
  }

  // 页面销毁:关闭全部弹窗,防止遮罩残留
  closeAllDialog() {
    this.dialogControllerList.forEach(ctrl => {
      try {
        ctrl.close();
      } catch (e) {
        LogUtil.warn("DialogUtil", "弹窗关闭异常", e);
      }
    });
    this.dialogControllerList = [];
  }
}

export default new DialogUtil();

四、页面标准生命周期规范示例(列表页面完整模板)

ets

复制代码
import StateView, { PageState } from '@ohos:har_base/components/common/StateView';
import RefreshListView from '@ohos:har_base/components/common/RefreshListView';
import DialogUtil from '@ohos:har_base/utils/dialog_util';
import LogUtil from '@ohos:har_base/utils/log_util';
import ThemeUtil from '@ohos:har_base/utils/theme';
import { Note } from '@ohos:har_note/model/Note';
import NoteDb from '@ohos:har_note/db/NoteRdb';

// 分页结构复用
interface PageInfo {
  pageIndex: number;
  pageSize: number;
  isNoMore: boolean;
}

@Entry
@Component
struct NoteListPage {
  @State pageState: PageState = PageState.LOADING;
  @State noteList: Note[] = [];
  @State page: PageInfo = {
    pageIndex: 0,
    pageSize: 10,
    isNoMore: false
  };

  async aboutToAppear() {
    await this.loadListData(true);
  }

  // 加载列表,isRefresh=true代表下拉刷新重置页码
  async loadListData(isRefresh: boolean) {
    if (isRefresh) {
      this.page.pageIndex = 0;
      this.page.isNoMore = false;
    }
    this.pageState = PageState.LOADING;
    try {
      const res = await NoteDb.queryList(this.page.pageIndex, this.page.pageSize);
      if (isRefresh) {
        this.noteList = res;
      } else {
        this.noteList = [...this.noteList, ...res];
      }

      if (this.noteList.length === 0) {
        this.pageState = PageState.EMPTY;
      } else {
        this.pageState = PageState.CONTENT;
        if (res.length < this.page.pageSize) {
          this.page.isNoMore = true;
        } else if (!isRefresh) {
          this.page.pageIndex += 1;
        }
      }
    } catch (err) {
      LogUtil.error("NoteList", "数据库查询失败", err);
      this.pageState = PageState.ERROR;
    }
  }

  // 页面销毁统一释放资源(强制规范)
  aboutToDisappear() {
    DialogUtil.closeAllDialog();
    NoteDb.closeDb();
    LogUtil.debug("NoteList", "页面销毁,资源全部释放");
  }

  build() {
    const color = ThemeUtil.getColor();
    const size = ThemeUtil.getSize();
    Column()
      .width("100%")
      .height("100%")
      .padding(size.gapMd)
      .backgroundColor(color.pageBg)
    {
      Text("我的笔记")
        .fontSize(size.fontTitle)
        .fontColor(color.textPrimary)
        .margin({ bottom: size.gapLg })

      StateView({
        state: this.pageState,
        onRetry: () => this.loadListData(true)
      }) {
        RefreshListView({
          list: this.noteList,
          page: this.page,
          onRefresh: () => this.loadListData(true),
          onLoadMore: () => this.loadListData(false)
        }) {
          (item: Note) => {
            Row()
              .width("100%")
              .padding(size.gapMd)
              .borderRadius(size.radiusMd)
              .backgroundColor(color.cardBg)
            {
              Column().layoutWeight(1) {
                Text(item.title)
                  .fontSize(size.fontMain)
                  .fontColor(color.textPrimary)
                Text(item.content)
                  .fontSize(size.fontAux)
                  .fontColor(color.textSecondary)
                  .margin({ top: size.gapXs })
              }
              Button("删除")
                .height(size.btnNormal)
                .backgroundColor(color.danger)
                .borderRadius(size.radiusSm)
                .onClick(() => {
                  DialogUtil.confirm({
                    content: "确定删除这条笔记?",
                    onConfirm: async () => {
                      await NoteDb.deleteById(item.id);
                      await this.loadListData(true);
                    }
                  })
                })
            }
          }
        }
      }
    }
  }
}

文末补充干货(CSDN 专属)

完整工程 module.json5 依赖配置模板

  1. har_base 无依赖

json

复制代码
"dependencies": []
  1. 业务 HAR har_note 仅依赖基础库

json

复制代码
"dependencies": [
  {
    "name": "har_base",
    "version": "1.0.0",
    "scope": "shared"
  }
]
  1. HSP 分包依赖基础 HAR + 对应业务 HAR

json

复制代码
"dependencies": [
  {"name":"har_base","version":"1.0.0","scope":"shared"},
  {"name":"har_note","version":"1.0.0","scope":"shared"}
]
  1. entry 主模块依赖所有 HAR、HSP

json

复制代码
"dependencies": [
  {"name":"har_base","version":"1.0.0","scope":"shared"},
  {"name":"har_note","version":"1.0.0","scope":"shared"},
  {"name":"har_user","version":"1.0.0","scope":"shared"},
  {"name":"hsp_note_editor","version":"1.0.0","scope":"shared"}
]

开发规范强制总结(收藏备查)

  1. 所有页面aboutToDisappear三件事:关闭全部弹窗、释放数据库、中断网络请求;
  2. 所有颜色、间距、字号禁止硬编码,统一读取 ThemeUtil;
  3. 网络请求全部使用 HttpUtil,自带 Loading、token 自动携带、401 登出处理;
  4. 列表统一使用 RefreshListView,内置下拉、上拉、防重复请求锁;
  5. 页面状态统一用 StateView,统一加载 / 空 / 错误兜底 UI;
  6. 全局配置、登录、深色模式全部通过 GlobalStore 管理,持久化自动落盘;
  7. 日志统一调用 LogUtil,自动脱敏敏感信息,生产环境关闭调试打印;
  8. 模块单向依赖,禁止业务 HAR 互相引用,杜绝循环依赖编译报错。
相关推荐
SuperHeroWu71 小时前
【HarmonyOS AI】DevEco CLI、Skills、知识库运用AI Coding提效详解
人工智能·华为·harmonyos
熊猫钓鱼>_>2 小时前
ArkUI 动画实战:从理论到交互,构建流畅的鸿蒙动效体验
华为·架构·交互·harmonyos·arkts·arkui·native
翰德恩咨询2 小时前
华为DSTE咨询洞察:如何撬动文化与氛围以支撑战略落地
华为·文化与氛围
Catrice02 小时前
HarmonyOS ArkTS 实战:实现一个校园宿舍电费查询与分摊应用
华为·harmonyos
驭渊的小故事2 小时前
UDP 和 TCP 网络知识和“Udp协议的回声服务器详细剖析”(5000字详细解析回升服务器的点点滴滴)(网络编程01)
网络
砚凝霜2 小时前
软考网络工程师|第 2 章 信道延迟、传输介质、数据编码、数字调制、PCM 完整备考笔记
网络·笔记·pcm
2301_768103492 小时前
HarmonyOS趣味相机实战第31篇:图片文档List、详情弹层与删除状态闭环
list·harmonyos·arkts·状态管理·arkui
woshihuanglaoshi2 小时前
数据迁移与版本管理 - Flutter在鸿蒙平台实现数据库升级策略
数据库·学习·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
aixingkong9212 小时前
Atlas 950 1024卡SuperPoD推测分析
网络·人工智能·硬件架构·硬件工程