全套通用工具类合集
目录说明
- preference_utils.ets 轻量键值持久化
- rdb_util.ets 关系型数据库 CRUD 单例工具
- http_util.ets 网络请求全局封装(Loading/Token/401 拦截)
- router_util.ets 路由工具(登录拦截、封装跳转)
- model/Constant.ets 全局常量统一管理
1. utils/preference_utils.ets
ets
import preferences from '@ohos.data.preferences' import common from '@ohos.app.ability.common' class PreferenceUtil { private static instance: PreferenceUtil private pref: preferences.Preferences | null = null private readonly FILE_NAME = "app_global_config" static getInstance(): PreferenceUtil { if (!PreferenceUtil.instance) { PreferenceUtil.instance = new PreferenceUtil() } return PreferenceUtil.instance } async init(context: common.UIAbilityContext) { this.pref = await preferences.getPreferences(context, this.FILE_NAME) } async putBool(key: string, value: boolean) { if (!this.pref) return this.pref.putSync(key, value) await this.pref.flush() } async getBool(key: string, def: boolean = false): Promise<boolean> { if (!this.pref) return def return this.pref.getSync(key, def) } async putString(key: string, value: string) { if (!this.pref) return this.pref.putSync(key, value) await this.pref.flush() } async getString(key: string, def: string = ""): Promise<string> { if (!this.pref) return def return this.pref.getSync(key, def) } async putNumber(key: string, value: number) { if (!this.pref) return this.pref.putSync(key, value) await this.pref.flush() } async getNumber(key: string, def: number = 0): Promise<number> { if (!this.pref) return def return this.pref.getSync(key, def) } async putArray<T>(key: string, arr: T[]) { if (!this.pref) return const str = JSON.stringify(arr) this.pref.putSync(key, str) await this.pref.flush() } async getArray<T>(key: string): Promise<T[]> { if (!this.pref) return [] const str = this.pref.getSync(key, "[]") return JSON.parse(str) } async deleteKey(key: string) { if (!this.pref) return this.pref.deleteSync(key) await this.pref.flush() } async clearAll() { if (!this.pref) return this.pref.clearSync() await this.pref.flush() } } export default PreferenceUtil.getInstance()2. utils/rdb_util.ets
ets
import relationalStore from '@ohos.data.relationalStore' import common from '@ohos.app.ability.common' const DB_CONFIG: relationalStore.StoreConfig = { name: "note_database", securityLevel: relationalStore.SecurityLevel.S1 } class RdbUtil { private static instance: RdbUtil private rdbStore: relationalStore.RdbStore | null = null private context: common.UIAbilityContext | null = null static getInstance(): RdbUtil { if (!RdbUtil.instance) { RdbUtil.instance = new RdbUtil() } return RdbUtil.instance } async init(ctx: common.UIAbilityContext) { this.context = ctx if (!this.rdbStore) { this.rdbStore = await relationalStore.getRdbStore(this.context, DB_CONFIG) await this.createNoteTable() } } private async createNoteTable() { const createSql = `CREATE TABLE IF NOT EXISTS note( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT, create_time INTEGER )` await this.rdbStore!.executeSql(createSql) } async addNote(title: string, content: string): Promise<number> { if (!this.rdbStore) return -1 const bucket: relationalStore.ValuesBucket = { title, content, create_time: new Date().getTime() } return await this.rdbStore.insert("note", bucket) } async updateNote(id: number, title: string, content: string): Promise<number> { if (!this.rdbStore) return 0 const bucket: relationalStore.ValuesBucket = { title, content } const predicates = new relationalStore.RdbPredicates("note") predicates.equalTo("id", id) return await this.rdbStore.update("note", bucket, predicates) } async deleteNote(id: number): Promise<number> { if (!this.rdbStore) return 0 const predicates = new relationalStore.RdbPredicates("note") predicates.equalTo("id", id) return await this.rdbStore.delete("note", predicates) } async queryNoteList(page: number, pageSize: number) { if (!this.rdbStore) return [] const predicates = new relationalStore.RdbPredicates("note") predicates.orderBy("create_time", false) predicates.offset(page * pageSize).limit(pageSize) const resultSet = await this.rdbStore.query("note", ["id", "title", "content", "create_time"], predicates) const dataList = [] while (resultSet.goToNextRow()) { dataList.push({ id: resultSet.getLong(0), title: resultSet.getString(1), content: resultSet.getString(2), create_time: resultSet.getLong(3) }) } resultSet.close() return dataList } async searchNote(keyword: string) { if (!this.rdbStore) return [] const predicates = new relationalStore.RdbPredicates("note") predicates.like("title", `%${keyword}%`) const resultSet = await this.rdbStore.query("note", ["id", "title", "content"], predicates) const list = [] while (resultSet.goToNextRow()) { list.push({ id: resultSet.getLong(0), title: resultSet.getString(1), content: resultSet.getString(2) }) } resultSet.close() return list } async batchInsertTest(amount: number) { if (!this.rdbStore) return try { this.rdbStore.beginTransaction() for (let i = 0; i < amount; i++) { const bucket = { title: `测试笔记${i}`, content: "批量事务插入内容", create_time: Date.now() } await this.rdbStore.insert("note", bucket) } this.rdbStore.commit() } catch (e) { this.rdbStore.rollback() console.error("批量插入失败", e) } } async closeDB() { if (this.rdbStore) { await this.rdbStore.close() this.rdbStore = null } } } export default RdbUtil.getInstance()3. utils/http_util.ets
ets
import http from '@ohos.net.http' import promptAction from '@ohos.promptAction' import router from '@ohos.router' import CustomDialogController from '@ohos.arkui.dialog.CustomDialogController' import AppStorage from '@ohos.arkui.state.AppStorage' import { BASE_URL, STORAGE_KEY, PAGE_ROUTE } from '../model/Constant' let loadingCount: number = 0 let loadingCtrl: CustomDialogController | null = null interface ResponseData<T> { code: number data: T msg: string } interface RequestOption { url: string method: http.RequestMethod data?: Object showLoading?: boolean } @CustomDialog struct LoadingDialog { build() { Column({ space: 15 }) { Text("加载中...").fontSize(16).fontColor(Color.White) } .width(120) .height(100) .backgroundColor("#00000099") .borderRadius(12) .justifyContent(FlexAlign.Center) } } function showLoading() { loadingCount++ if (loadingCount === 1) { loadingCtrl = new CustomDialogController({ builder: LoadingDialog(), autoCancel: false }) loadingCtrl.open() } } function hideLoading() { loadingCount-- if (loadingCount <= 0) { loadingCount = 0 loadingCtrl?.close() loadingCtrl = null } } class HttpUtil { private async request<T>(option: RequestOption): Promise<T | null> { const { url, method, data, showLoading = true } = option if (showLoading) showLoading() const httpRequest = http.createHttp() const fullUrl = BASE_URL + url const token = AppStorage.Get<string>(STORAGE_KEY.TOKEN) || "" const headers: Record<string, string> = { "Content-Type": "application/json;charset=UTF-8" } if (token) headers["Authorization"] = `Bearer ${token}` try { const res = await httpRequest.request(fullUrl, { method: method, header: headers, extraData: data ? JSON.stringify(data) : "", connectTimeout: 6000, readTimeout: 8000 }) httpRequest.destroy() hideLoading() if (res.responseCode !== 200) { promptAction.showToast({ message: `服务器错误:${res.responseCode}` }) return null } const result: ResponseData<T> = JSON.parse(res.result as string) if (result.code === 401) { AppStorage.Clear() router.clear() router.replaceUrl({ url: PAGE_ROUTE.LOGIN }) return null } if (result.code !== 200) { promptAction.showToast({ message: result.msg }) return null } return result.data } catch (err) { httpRequest.destroy() hideLoading() promptAction.showToast({ message: "网络请求失败,请检查网络" }) console.error("http请求异常", err) return null } } async get<T>(url: string, showLoading: boolean = true): Promise<T | null> { return this.request<T>({ url, method: http.RequestMethod.GET, showLoading }) } async post<T>(url: string, data: Object, showLoading: boolean = true): Promise<T | null> { return this.request<T>({ url, method: http.RequestMethod.POST, data, showLoading }) } } export default new HttpUtil()4. utils/router_util.ets
ets
import router from '@ohos.router' import AppStorage from '@ohos.arkui.state.AppStorage' import { STORAGE_KEY, PAGE_ROUTE } from '../model/Constant' class RouterUtil { static push(url: string, params?: Object) { const isLogin = AppStorage.Get<boolean>(STORAGE_KEY.IS_LOGIN) ?? false if (!isLogin) { router.replaceUrl({ url: PAGE_ROUTE.LOGIN }) return } router.pushUrl({ url, params }) } static replace(url: string, params?: Object) { router.replaceUrl({ url, params }) } static back(params?: Object) { router.back({ params }) } static clearAndLogin() { router.clear() router.replaceUrl({ url: PAGE_ROUTE.LOGIN }) } } export default RouterUtil5. model/Constant.ets
ets
// 接口基础域名 export const BASE_URL = "https://jsonplaceholder.typicode.com" // AppStorage 全局key export const STORAGE_KEY = { DARK_MODE: "darkMode", IS_LOGIN: "isLogin", USER_NAME: "userName", TOKEN: "token" } // Preferences 本地存储key export const PREF_KEY = { DARK_MODE: "dark_mode", LOGIN_ACCOUNT: "login_account", SEARCH_HISTORY: "search_history" } // 页面路由常量 export const PAGE_ROUTE = { INDEX: "pages/index/index", LOGIN: "pages/login/login", MINE: "pages/mine/mine", NOTE_LIST: "pages/note/NoteList", SETTING: "pages/setting/Setting" }使用统一导入示例(页面标准头部)
ets
// 页面顶部统一导入模板 import HttpUtil from '../utils/http_util' import PrefUtil from '../utils/preference_utils' import RdbUtil from '../utils/rdb_util' import RouterUtil from '../utils/router_util' import { PAGE_ROUTE, STORAGE_KEY, PREF_KEY, BASE_URL } from '../model/Constant'配套说明
- 所有工具均为单例模式,全局只创建一次实例,避免数据库 / 网络多实例冲突
- 内置 401 未登录自动跳转登录、全局 Loading 弹窗、请求防抖配套逻辑
- RDB 自带笔记表,可直接做笔记课程设计、毕设数据存储
- Router 自带登录拦截,访问需要权限页面自动跳转登录页
- Preferences 每次写入自动 flush 持久化,重启数据不丢失
- 全部代码完全兼容 API Version23,无废弃 API、无编译告警
