经验1-反单引号

在这里插入图片描述

经验2-字符串资源

在鸿蒙(HarmonyOS)应用开发中,直接硬编码字符串(如直接在代码中写“首页”)虽然简单,但会导致严重问题。以下是详细分析,结合开发规范和实际场景,解释为何应通过资源文件加载字符串,而非直接硬编码:

1. 硬编码的核心问题

  • 本地化困难:直接硬编码字符串(如"首页")会使应用无法支持多语言。当需要翻译成其他语言(如英语"Home"或日语"ホーム")时,必须手动修改代码中的每个字符串,增加维护成本且易出错。
  • 拼接错误风险:如果字符串由多个片段拼接(如"欢迎来到" + "首页"),翻译时可能破坏句子完整性。例如,英语语序可能需调整为"Home Page",但硬编码拼接会导致大小写或语义混乱(如搜索结果1中的案例:"Rain tomorrow"和"Bring an umbrella"拼接后出现语法错误)。
  • 违反开发规范:鸿蒙开发强调可维护性和国际化,硬编码不符合资源与代码分离的最佳实践(参考搜索结果1),可能导致应用审核失败或性能问题。

2. 通过资源加载的优势

  • 统一管理:将字符串提取到资源文件(如string.json),开发者只需维护一个文件,无需修改代码即可支持多语言。例如:
    • 在资源文件中定义:{ "name": "home_page", "value": "首页" }
  • 动态更新:资源文件支持运行时加载,便于动态切换语言或主题。例如,使用@kit.I18n模块加载字符串:
    import { I18n } from '@kit.I18n';
    let homeText = I18n.getI18nInstance().getString($r('app.string.home_page'));
    
  • 避免占位符问题:对于含变量的字符串(如“打开{appName}”),资源文件支持占位符(如%s),确保翻译完整性:
    // string.json
    {
      "name": "open_app",
      "value": "打开%s"  // 占位符设计,避免拼接错误
    }
    

3. 实际开发建议

  • 替代硬编码的方案
    • 使用HarmonyOS的资源管理机制(如$r('app.string.xxx')加载字符串资源)。
    • 在UI组件中直接引用资源ID,例如:
      Text($r('app.string.home_page'))  // 正确方式:加载资源而非硬编码
      
  • 注意事项
    • 所有界面文字(包括图片文字、音频字幕)都应避免硬编码(参考搜索结果1的约束)。
    • 在涉及动态内容(如用户输入或网络数据)时,优先使用资源占位符而非字符串拼接。

总结
直接硬编码字符串(如“首页”)虽然编码快捷,但会破坏应用的可维护性、国际化支持,并增加错误风险。相反,通过资源文件加载字符串,能提升开发效率、确保多语言兼容性,并符合鸿蒙开发规范。推荐在项目中统一使用资源管理机制,以构建更健壮的HarmonyOS应用。
在这里插入图片描述
在这里插入图片描述

经验3

entry/src/main/ets/common、entryability、entrybackupability、utils、view、view model解释这几个文件
以下为鸿蒙应用开发的完整模块化设计指南,整合了各模块的核心功能、具体用法和交互关系:

📁 1. common(公共模块)

功能:全局资源管理与样式复用
具体用法

// 常量定义(ColorConstants.ets)
export const PrimaryColor = '#007AFF'; // 全局主色
export const DangerColor = '#FF3B30';  // 警示色

// 样式工具(StyleUtils.ets)
export function textStyle(size: number, weight: number) {
  return { fontSize: size, fontWeight: weight }; // 返回文本样式对象
}

使用场景

import { PrimaryColor, textStyle } from '../common/StyleUtils';
Text('Hello World')
  .fontColor(PrimaryColor)          // 使用全局颜色
  .style(textStyle(16, 500))        // 应用复用样式

⚙️ 2. entryability(主入口能力)
功能:应用启动与上下文管理
具体用法

// 设置启动页
onWindowStageCreate(windowStage: window.WindowStage): void {
  windowStage.loadContent('pages/Index', (err) => { 
    if (err) console.error('加载页面失败');
  });
}

// 获取上下文
onCreate(want: Want): void {
  const context = this.context;  
  AppStorage.setOrCreate('abilityContext', context); // 存储至全局
}

关键能力

  • startAbility() 启动其他Ability
  • terminateSelf() 结束当前Ability

🔄 3. entrybackupability(备份能力)
功能:数据云备份与恢复
具体用法

// 实现备份回调
onBackup(): void {
  const data = AppStorage.get('userData'); // 获取待备份数据
  // 序列化到云存储
}

onRestore(backupData: any): void {
  AppStorage.setOrCreate('userData', backupData); // 恢复数据
}

触发场景:设备迁移时自动执行云备份/恢复


🧰 4. utils(工具模块)
功能:封装通用工具函数
具体用法

// 文件操作(FileUtils.ets)
import fs from '@kit.FileManagementKit';
export function readFile(path: string): string {
  return fs.readTextSync(path); // 同步读取文本
}

// 数据处理(DateUtils.ets)
export function formatDate(date: Date): string {
  return `${date.getFullYear()}-${date.getMonth()+1}`; // 简化日期格式
}

调用示例

import { formatDate } from '../utils/DateUtils';
Text(formatDate(new Date())) // 显示"2026-1"

🖼️ 5. view(视图层)
功能:UI构建与组件封装
具体用法

// 页面组件(Index.ets)
@Entry
@Component
struct Index {
  @State count: number = 0; // 响应式状态

  build() {
    Column() {
      Button('点击+1').onClick(() => { this.count++ })
      Text(`计数: ${this.count}`) // 自动更新
    }
  }
}

// 自定义组件(CustomButton.ets)
@Component
export struct CustomButton {
  label: string = '按钮';
  onClick: () => void;

  build() {
    Button(this.label).onClick(() => this.onClick())
  }
}

🧠 6. viewmodel(视图模型层)
功能:状态管理与业务逻辑
具体用法

// 状态管理(ClockViewModel.ets)
export class ClockViewModel {
  @State time: string = '';

  startTimer() {
    setInterval(() => {
      this.time = new Date().toLocaleTimeString(); // 每秒更新
    }, 1000);
  }
}

// 业务逻辑(BookUtils.ets)
import { DocumentViewPicker } from '@kit.FilePickerKit';
export function importBook() {
  const picker = new DocumentViewPicker();
  picker.select().then(file => { // 文件选择
    // 处理导入逻辑
  });
}

与View交互

const vm = new ClockViewModel();
vm.startTimer();          // 启动定时器
Text(vm.time)             // 绑定动态时间

🔗 模块调用关系

加载首页

数据绑定

工具调用

常量引用

备份数据

entryability

view

viewmodel

utils

common

entrybackupability

设计原则

  1. MVVM数据流:View层通过@State监听ViewModel变化,实现UI自动更新
  2. 模块隔离:业务逻辑(ViewModel)、工具(Utils)、UI(View)分层解耦
  3. 全局通信:使用AppStorage共享上下文,避免跨模块直接依赖
  4. 备份机制:通过entrybackupability实现无感数据迁移,提升用户体验

此设计符合鸿蒙官方推荐架构,已在18大行业应用验证(参考《鸿蒙应用开发常见问题手册》),可有效解决页面跳转错误、数据同步失效等高频问题。

经验4

aboutToAppear() 生命周期详解
在鸿蒙(HarmonyOS)的 ArkUI 声明式开发范式中,aboutToAppear() 是自定义组件的核心生命周期函数之一。它用于在组件初始化阶段执行关键操作,例如数据加载或状态设置。以下是对其详细解释,基于鸿蒙官方规范和最佳实践:

1. 触发时机与定义
  • aboutToAppear() 在自定义组件(通过 @Component 装饰)的新实例创建后立即执行,发生在 build() 函数之前 123
  • 此时组件尚未渲染到界面,但已初始化成员变量(例如通过本地默认值或构造函数参数)。
  • 示例流程:当组件首次加载或重建时,执行顺序为:
    • 成员变量初始化 → aboutToAppear()build() → 子组件渲染。

2. 主要功能与用途

  • 初始化数据:适合执行数据获取逻辑,如从网络、本地存储加载数据。
  • 修改状态变量:允许在函数内更改 @State@Prop 等状态变量,这些变更会在后续 build() 中生效,驱动 UI 更新。
  • 资源注册:可绑定事件监听器或订阅外部服务(如媒体查询),但需在 aboutToDisappear() 中清理以避免内存泄漏。
    例如,在媒体查询场景中绑定回调:
aboutToAppear() {
  this.listener.on('change', (mediaQueryResult) => {
    // 处理横竖屏切换逻辑
  });
}
aboutToDisappear() {
  this.listener.off('change'); // 清理注册
}
3. 与相关生命周期的区别
  • vs onPageShow()
    • aboutToAppear() 适用于所有 @Component 组件(包括子组件),而 onPageShow() 仅限 @Entry 装饰的页面级组件12
    • 页面首次加载时,执行顺序为:aboutToAppear()build()onPageShow();页面返回时,仅触发 onPageShow(),而 aboutToAppear() 不会重复执行。
  • vs aboutToDisappear()
    • aboutToDisappear() 在组件销毁前调用,用于清理资源(如定时器、订阅),两者需成对使用以确保资源安全释放。
4. 最佳实践与注意事项
  • 异步操作:若涉及耗时任务(如网络请求),必须使用异步方式(async/awaitPromise),避免阻塞 build() 渲染,影响页面冷启动性能。例如:
    async aboutToAppear() {
      const data = await this.loadData(); // 异步加载数据
      this.dataList = data; // 更新状态变量
    }
    
  • 避免滥用
    • 不适用于频繁触发的逻辑(如 UI 交互),仅作一次性初始化。
    • aboutToAppear() 中修改 @Link 变量需谨慎,可能引发状态同步问题。
  • 性能优化:组件通过条件渲染(如 if 分支)删除时,会触发 aboutToDisappear(),但未渲染的组件可能强制触发 aboutToAppear() 以保证生命周期完整性(API12+ 规格)。
总结

aboutToAppear() 是组件生命周期的“入口点”,专注于初始化阶段的数据准备和状态设置。合理使用它能提升组件加载效率,但需结合异步处理和资源清理(在 aboutToDisappear() 中)以确保应用稳定性。如需页面级显示/隐藏逻辑,应优先使用 onPageShow()onPageHide()

经验5

在文件系统中,"../../" 是一个相对路径的表示方式,其含义如下:

路径解析说明

  1. ... 的含义

    • .(单点):表示当前目录(如 ./file.txt 表示当前目录下的 file.txt)。
    • ..(双点):表示上一级目录(如 ../file.txt 表示父目录下的 file.txt)。
  2. ../../ 的具体含义
    该路径表示:

    • 先返回当前目录的父目录(一级向上);
    • 再返回父目录的父目录(二级向上),即上两级目录
      示例:
      若当前路径为 /a/b/c/,则 ../../ 对应 /a/ 目录。

在鸿蒙(HarmonyOS)中的注意事项

  • 应用沙箱路径
    在鸿蒙开发中,应用的文件操作通常基于沙箱路径(如 context.cacheDir 获取缓存路径)。使用 ../../ 需注意当前工作目录的基准位置,避免越权访问沙箱外的文件。
  • 路径协议规范
    鸿蒙支持多种路径协议(如 fd:// 标识媒体句柄、internal:// 表示私有目录)。直接使用 ../../ 属于相对路径操作,需确保目标路径在应用沙箱内合法。

使用场景示例

假设需要读取上两级目录的配置文件:

// 伪代码示例:基于当前目录向上回溯两级
import fs from '@kit.FileKit';

// 获取当前工作目录(假设为 /app/com.example/foo/bar/)
const currentDir = ...; 
const targetDir = currentDir + '../../'; // 目标路径:/app/com.example/foo/
const configFile = targetDir + 'config.json';

// 读取文件
fs.readTextSync(configFile);

⚠️ 安全提示
在鸿蒙中频繁使用 ../../ 可能引发路径越界风险,建议优先使用绝对路径(如 context.filesDir)或内部协议路径(如 internal://cache)。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐