当前位置: 首页 > news >正文

全套通用工具类合集

目录说明

  1. preference_utils.ets 轻量键值持久化
  2. rdb_util.ets 关系型数据库 CRUD 单例工具
  3. http_util.ets 网络请求全局封装(Loading/Token/401 拦截)
  4. router_util.ets 路由工具(登录拦截、封装跳转)
  5. 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 RouterUtil

5. 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'

配套说明

  1. 所有工具均为单例模式,全局只创建一次实例,避免数据库 / 网络多实例冲突
  2. 内置 401 未登录自动跳转登录、全局 Loading 弹窗、请求防抖配套逻辑
  3. RDB 自带笔记表,可直接做笔记课程设计、毕设数据存储
  4. Router 自带登录拦截,访问需要权限页面自动跳转登录页
  5. Preferences 每次写入自动 flush 持久化,重启数据不丢失
  6. 全部代码完全兼容 API Version23,无废弃 API、无编译告警
http://www.jsqmd.com/news/1171532/

相关文章:

  • 校园网IP地址深度解析:从私有地址172.20.x.x到公网访问的3层NAT转换
  • Anaconda 2024.10 国内镜像配置:3步解决 pip/conda 下载超时与速度慢
  • Java构建工具终极指南:openEuler维护的Maven与Gradle深度对比
  • LTC1864与PIC18F56K42高精度ADC信号采集方案详解
  • 8张RTX 4090部署DeepSeek大模型:性能测试与优化实战
  • 终极指南:如何在Mac上免费解锁视频预览功能——QLVideo完整安装与使用教程
  • Tool、Skill、Sub-Agent 散成一地?PluginDescriptor 一次打成业务插件
  • ATLAS200 NUP 模块SD卡制卡方法
  • CV智能涌现为何落后NLP?多模态数据与统一架构是关键
  • 执行一条 select 语句,期间发生了什么?
  • 仅限首批认证开发者获取:DeepSeek V3 专属Tokenizer训练套件(含中文法律/医疗/金融领域子词表)
  • 为什么选择openeuler/yocto-meta-virtualization?虚拟化层构建的核心优势解析
  • TEKLauncher:ARK生存进化MOD管理与服务器连接终极解决方案
  • 赛豆科技 AIVA 汽车智能体架构演进面试题与答案
  • 闲谈《道德经》014|夷希入微
  • R语言中1-Way ANOVA与ANCOVA选择指南:从混杂控制到交互诊断
  • C++实现人工势场法机器人路径规划:从原理到可视化仿真实战
  • AI Agent生产级开发实战:基于Hermes框架的工程化实践指南
  • StyleDrive:首个驾驶风格感知的端到端自动驾驶基准
  • Hive 4.2.0 实战:从建表到50道SQL题,3小时掌握核心查询技巧
  • 模板驱动型文档自动化:四维模型重构内容生产
  • 树莓派3音乐播放实战:从无声到稳定播放的完整指南
  • PyInstaller 5.13.2 资源文件打包:3种路径获取方法对比与临时目录解析
  • PyTorch CNN实战手记:从梯度爆炸到部署落地的硬核细节
  • 如何快速配置英雄联盟自动化工具:新手完整入门指南
  • UFT vs Selenium:图书管理系统自动化测试的5个关键决策点对比
  • Copilot PPT智能排版失效的7大陷阱(微软官方未公开的Prompt避坑指南)
  • 多维聚合中的数据操纵本质:维度关系重构与5类高危操作
  • 深耕高空作业装备领域,郑州小金牛新能源打造电动脚手架升降机一体化解决方案
  • STM32G071RB与TC78H653FTG的直流有刷电机控制方案