一、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 依赖配置模板
- har_base 无依赖
json
"dependencies": []
- 业务 HAR har_note 仅依赖基础库
json
"dependencies": [
{
"name": "har_base",
"version": "1.0.0",
"scope": "shared"
}
]
- HSP 分包依赖基础 HAR + 对应业务 HAR
json
"dependencies": [
{"name":"har_base","version":"1.0.0","scope":"shared"},
{"name":"har_note","version":"1.0.0","scope":"shared"}
]
- 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"}
]
开发规范强制总结(收藏备查)
- 所有页面
aboutToDisappear三件事:关闭全部弹窗、释放数据库、中断网络请求; - 所有颜色、间距、字号禁止硬编码,统一读取 ThemeUtil;
- 网络请求全部使用 HttpUtil,自带 Loading、token 自动携带、401 登出处理;
- 列表统一使用 RefreshListView,内置下拉、上拉、防重复请求锁;
- 页面状态统一用 StateView,统一加载 / 空 / 错误兜底 UI;
- 全局配置、登录、深色模式全部通过 GlobalStore 管理,持久化自动落盘;
- 日志统一调用 LogUtil,自动脱敏敏感信息,生产环境关闭调试打印;
- 模块单向依赖,禁止业务 HAR 互相引用,杜绝循环依赖编译报错。