HarmonyOS 7 实战开发 05:把页面做到可上线状态
前面四篇把工作台的框架、交互、性能、适配都搞定了,页面看着已经挺像那么回事。但离真正上线还有距离——用户打开应用不能白屏,断网不能直接崩,退出再进来状态不能丢。这篇讲工程收尾的事情,都是细节,但没做好就是没法上线。
很多人开发的时候只顾着功能实现,忽略了异常处理和数据持久化。Demo 阶段没问题,真给用户用,各种奇奇怪怪的问题都来了。这篇就把我们项目上线前做的那些收尾工作讲一讲。

数据持久化:Preferences 存用户偏好
用户上次打开应用时选了哪个导航、滚动到了哪里,这些信息要存下来。下次打开应用直接恢复,不用用户重新操作一遍。
HarmonyOS 提供了 Preferences 轻量存储,适合存小的键值对。我们项目里存了用户的主题选择、默认导航项、上次阅读位置。
下面是封装的 Preferences 工具类,文件位置在 utils/PreferenceUtil.ets:
import preferences from '@ohos.data.preferences';
export class PreferenceUtil {
private static preferencesInstance: preferences.Preferences | null = null;
private static readonly STORE_NAME = 'workbench_prefs';
// 初始化 Preferences
static async init(context: Context) {
if (!this.preferencesInstance) {
this.preferencesInstance = await preferences.getPreferences(
context,
this.STORE_NAME
);
}
}
// 保存选中的导航 ID
static async saveSelectedNavId(navId: number) {
await this.preferencesInstance?.put('selected_nav_id', navId);
await this.preferencesInstance?.flush();
}
// 读取选中的导航 ID
static async getSelectedNavId(): Promise {
const value = await this.preferencesInstance?.get('selected_nav_id', 0);
return value as number;
}
// 保存上次阅读位置
static async saveLastReadPosition(itemId: string) {
await this.preferencesInstance?.put('last_read_item', itemId);
await this.preferencesInstance?.flush();
}
// 清除所有数据(退出登录时用)
static async clear() {
await this.preferencesInstance?.clear();
await this.preferencesInstance?.flush();
}
}
在 EntryAbility 的 onCreate 里初始化,页面 aboutToAppear 的时候读取。这样用户每次打开应用,都能回到上次离开的位置。
注意:Preferences 是异步的,不要在 build 方法里同步调用。读取数据放在 aboutToAppear 里,读到了再更新 @State,UI 自动刷新。
异常兜底:断网、空数据、加载失败
用户打开应用,网络慢怎么办?接口报错怎么办?列表是空的怎么办?这些情况都要有兜底 UI,不能直接白屏或者崩掉。
我们在 ContentList 组件里做了三态处理:加载中、空数据、错误。之前第二篇讲过思路,这里讲一下具体的异常处理逻辑:
@Component
export struct ContentList {
@Prop items: ContentItem[] = [];
@Prop isLoading: boolean = false;
@Prop errorMsg: string = '';
onRetry: () => void = () => {};
build() {
if (this.isLoading) {
// 加载中:显示 loading
this.LoadingView()
} else if (this.errorMsg) {
// 错误状态:显示错误信息和重试按钮
this.ErrorView()
} else if (this.items.length === 0) {
// 空数据:显示空状态提示
this.EmptyView()
} else {
// 正常列表
this.NormalListView()
}
}
@Builder
LoadingView() {
Column() {
LoadingProgress()
.width(40)
.height(40)
Text('加载中...')
.fontSize(14)
.fontColor('#999999')
.margin({ top: 12 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
@Builder
ErrorView() {
Column() {
Text(this.errorMsg)
.fontSize(14)
.fontColor('#ff4444')
.textAlign(TextAlign.Center)
Button('重新加载')
.margin({ top: 16 })
.backgroundColor('#007aff')
.onClick(() => {
this.onRetry();
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
@Builder
EmptyView() {
Column() {
Text('暂无内容')
.fontSize(14)
.fontColor('#999999')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
这套三态处理看起来简单,但真到线上很重要。我们上线前测试了弱网、断网、接口超时等各种情况,确保每种状态都有友好提示,不会出现白屏或者崩溃。

全局错误处理
除了页面级的异常处理,还要有全局的错误兜底。应用启动的时候注册全局错误监听,未捕获的异常不会直接闪退,而是提示用户应用出错了,然后自动重启。
这个一般在 EntryAbility 里配置。我们项目里用了 try-catch 包裹关键流程,同时监听系统的 error 事件,把错误信息上报到日志系统,方便后续排查问题。
上线前的性能检查清单
功能写完了,上线前一定要做一轮性能检查。我们整理了一个清单:
1. 启动速度:冷启动时间要控制在 2 秒以内。用 DevEco Studio 的启动分析工具看,有没有耗时操作放在了主线程。
2. 内存占用:连续操作 10 分钟,看内存有没有持续上涨。如果有,大概率是内存泄漏。重点检查图片缓存、事件监听有没有及时释放。
3. 列表滑动流畅度:在低端机上滑动列表,FPS 能不能稳定在 50 以上。掉帧多的话回头看第三篇的优化方法。
4. 电量消耗:后台运行一段时间,看耗电量是否正常。定时器、网络请求不要太频繁。
5. 多机型适配:手机、折叠屏、平板都跑一遍,确认布局没有问题。横竖屏切换也测一下,状态有没有丢失。
工程收尾的其他细节
日志规范:开发的时候 console.log 到处都是,上线前要清理掉。封装一个 Logger 工具类,debug 模式打日志,release 模式自动关闭。
代码规范:统一命名规范,删掉注释掉的无用代码。TS 类型检查要严格,不要用 any。
版本号管理:app.json5 里的 versionCode 和 versionName 要更新。每次发版都要递增,不然应用市场检测不出来新版本。
这些都是小事,但上线前不做,后面改起来很麻烦。
写在最后
五篇连载到这里就结束了。从最开始搭工程框架,到状态管理、性能优化、多设备适配,最后到工程收尾上线。整个过程走下来,其实就是一个真实项目的开发流程。
HarmonyOS 7 的开发体验比之前好了很多,ArkUI 的声明式写法效率很高,响应式布局和状态管理的思路也和前端很像。但真要做出一个稳定流畅的应用,还是要在细节上下功夫——性能、适配、异常处理,哪一块没做到位,用户体验都会打折扣。
希望这个系列对大家做鸿蒙开发有帮助。有问题欢迎交流。
更多推荐



所有评论(0)