【开源鸿蒙跨平台开发先锋训练营】基于Flutter实现鸿蒙App之体验和发布优化
本文记录了项目体验与发布优化的实现过程。主要优化点包括:1)将生产环境中的print和LogInterceptor改为仅在Debug模式下执行,避免性能影响和数据泄露;2)优化详情页返回收藏页时的整表重载问题,改为仅更新被操作项。通过kDebugMode判断和debugPrint替换,以及Navigator结果传递机制,实现了日志控制精准化和列表增量更新。这些优化显著提升了应用性能和安全性能,特别
·
这里对项目进行体验和发布优化。
文章目录
性能优化:体验与发布优化
记录本项目的 体验与发布 优化过程 ,含实现方式与涉及代码。
一、实现的目标
- 1 生产环境中的 print 与 LogInterceptor:大量
print和完整 body 日志在真机/Release 下仍会执行,影响性能且可能泄露数据;flutter_lints默认会提示avoid_print。需将print改为仅在 Debug 下输出,并在 Release 下关闭或减弱LogInterceptor。 - 2 详情页返回后收藏页整表重载:每次从详情返回收藏页都会重新
getFavoriteWorks()并整表刷新,列表较长时会有明显重绘和多图重新请求。改为返回时只更新被操作的那一条(通过 Navigator 的 result 传回workId与isFavorite),本地从列表删除该项(取消收藏时),避免全量_load()。
对应文档:.doc/性能优化建议.md
二、实现思路
- 1:
- 在
lib/api/api_service.dart、lib/pages/home_page.dart中,将所有print(...)改为if (kDebugMode) debugPrint(...),使 Release 构建下不执行日志输出。 - 将
LogInterceptor的requestBody、responseBody、error改为仅在kDebugMode为 true 时开启,Release 下不再打印请求/响应 body,避免性能与数据泄露。
- 在
- 2:
- 详情页(
WorkDetailPage)在用户点击返回时,Navigator.pop(context, {'workId': widget.work.id, 'isFavorite': _isFavorite}),把当前作品的 id 与离开时的收藏状态带回。 - 收藏页(
FavoritesPage)在push详情页后使用await Navigator.push<Map<String, dynamic>>(...)接收 result;若 result 非空且isFavorite == false,则从_works中移除该workId并setState,不再调用_load()做整表重载。
- 详情页(

三、修改文件
| 文件 | 说明 |
|---|---|
lib/api/api_service.dart |
增加 import 'package:flutter/foundation.dart';LogInterceptor 的 requestBody/responseBody/error 改为 kDebugMode;三处 print 改为 if (kDebugMode) debugPrint(...)。 |
lib/pages/home_page.dart |
增加 import 'package:flutter/foundation.dart';_loadData 内所有 print 改为 if (kDebugMode) debugPrint(...)。 |
lib/pages/work_detail_page.dart |
两处返回按钮的 Navigator.of(context).pop() 改为 Navigator.of(context).pop(<String, dynamic>{'workId': widget.work.id, 'isFavorite': _isFavorite})(仅关闭详情页的 pop,分享面板等 pop 不变)。 |
lib/pages/favorites_page.dart |
打开详情改为 push<Map<String, dynamic>> 并 await result;新增 _applyDetailResult(result, work.id),在 result 中 isFavorite == false 时从 _works 移除对应项并 setState;不再在返回时调用 _load()。 |
四、实现要点
1 日志与 LogInterceptor
- 为何用
kDebugMode+debugPrint?kDebugMode在 Release 构建下为 false,条件内的debugPrint不会执行,既满足「Release 不打日志」又无需引入 logger 包。debugPrint在 Debug 下会做输出节流,避免刷屏。 - LogInterceptor:
requestBody: kDebugMode、responseBody: kDebugMode、error: kDebugMode,这样 Release 下拦截器仍存在但不打印 body 与 error,仅保留必要请求行为。
2 收藏页增量更新
- 详情页返回结果:只在对「页面」执行 pop 时传 result(返回按钮);分享面板、复制链接等对 BottomSheet 的 pop 不传 result,不影响。
- 收藏页逻辑:
_applyDetailResult(result, tappedWorkId)仅在result != null、result['workId'] == tappedWorkId且result['isFavorite'] == false时,从_works中移除该 work 并setState。若用户在详情页取消收藏,列表只删一条;若未改收藏或改为收藏,列表无需变更(收藏页只展示已收藏,取消收藏即删除该项)。 - 无 result 或类型不符:不执行全量
_load(),避免从详情返回时无谓的整表重载与多图重新请求。
五、关键代码位置
1 ApiService(api_service.dart)
- LogInterceptor:
_dio!.interceptors.add(LogInterceptor(
requestBody: kDebugMode,
responseBody: kDebugMode,
error: kDebugMode,
));
- 日志:
if (kDebugMode) debugPrint('尝试请求数据 (第 ${attempts + 1} 次)...');及请求失败/异常处的同类写法。
2 HomePage(home_page.dart)
- 日志:
_loadData内所有原print(...)改为if (kDebugMode) debugPrint(...)或if (kDebugMode) { debugPrint(...); }。
3 WorkDetailPage(work_detail_page.dart)
- 返回带 result:两处返回按钮(无图时的返回、有图时的返回)中:
Navigator.of(context).pop(<String, dynamic>{'workId': widget.work.id, 'isFavorite': _isFavorite});
4 FavoritesPage(favorites_page.dart)
- 打开详情并应用 result:
final result = await Navigator.of(context).push<Map<String, dynamic>>(
MaterialPageRoute(
builder: (context) => WorkDetailPage(work: work, initialIndex: 0),
),
);
_applyDetailResult(result, work.id);
- 增量更新:
void _applyDetailResult(Map<String, dynamic>? result, String tappedWorkId) {
if (result == null || !mounted) return;
final workId = result['workId'] as String?;
final isFavorite = result['isFavorite'] as bool?;
if (workId == null || workId != tappedWorkId) return;
if (isFavorite == false) {
setState(() => _works = _works.where((w) => w.id != workId).toList());
}
}
六、注意事项
- 1:示例/测试文件(如
lib/utils/data_parser_example.dart、lib/api/api_example.dart)中的print未在本期修改,若需发布或静态检查通过可另行改为debugPrint或删除。 - 2:首页、发现页从详情返回时未使用 result,仍保持原有行为;仅收藏页使用 result 做增量更新,与「从收藏进入详情并取消收藏」场景一致。
七、小结
通过 1 将 API 与首页的 print 改为仅在 kDebugMode 下执行的 debugPrint,并将 LogInterceptor 的 body/error 日志限定在 Debug 模式,Release 包不再输出敏感与冗长日志,有利于性能与安全;通过 2 在详情页返回时传递 workId 与 isFavorite,收藏页根据 result 仅删除被取消收藏的一条并刷新列表,避免详情返回后的整表重载与多余网络/解码,提升体验。
结束语
感谢阅读本帖,如对贴中内容有意见和建议的,欢迎与我联系交流,也欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)