#跟着若城学鸿蒙# 解决页面跳转时数据丢失
·
问题场景描述
在鸿蒙应用开发中,我们经常遇到这样的问题:从Page A跳转到Page B时,通过router.pushUrl()传递的复杂对象数据在页面间丢失或解析失败。特别是在传递自定义类对象或大数据量时,这个问题尤为突出。
根本原因分析
- 序列化限制:鸿蒙的页面路由只支持基本数据类型和可序列化的简单对象
- 数据大小限制:单次传递数据超过100KB时可能出现截断
- 生命周期差异:页面跳转时原页面的数据可能已被回收
解决方案一:使用全局数据总线
// 1. 创建全局数据管理器
class DataBus {
private static instance: DataBus;
private dataMap: Map<string, Object> = new Map();
public static getInstance(): DataBus {
if (!DataBus.instance) {
DataBus.instance = new DataBus();
}
return DataBus.instance;
}
public setData(key: string, data: Object): void {
this.dataMap.set(key, data);
}
public getData(key: string): Object | undefined {
return this.dataMap.get(key);
}
}
// 2. 在Page A设置数据
DataBus.getInstance().setData('userInfo', {
name: '张三',
age: 28,
avatar: 'base64...'
});
// 3. 在Page B获取数据
let user = DataBus.getInstance().getData('userInfo');
解决方案二:使用持久化存储
// 1. 使用Preferences存储
import preferences from '@ohos.data.preferences';
async function saveData(context) {
try {
let pref = await preferences.getPreferences(context, 'mydata');
await pref.put('complexObj', JSON.stringify(complexData));
await pref.flush();
} catch (e) {
console.error(`保存失败: ${e}`);
}
}
// 2. 在目标页面读取
async function loadData(context) {
let pref = await preferences.getPreferences(context, 'mydata');
let dataStr = await pref.get('complexObj', 'default');
return JSON.parse(dataStr);
}
解决方案三:优化路由传参方式
// 1. 将复杂对象转换为字符串
let params = {
id: 123,
data: encodeURIComponent(JSON.stringify(complexData))
};
// 2. 通过URL传递
router.pushUrl({
url: 'pages/PageB',
params: params
});
// 3. 在Page B解析
onPageShow() {
let uri = router.getParams();
let complexData = JSON.parse(decodeURIComponent(uri.data));
}
性能对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 全局数据总线 | 内存访问快 | 应用重启会丢失 | 单次会话内的数据共享 |
| 持久化存储 | 数据可保留 | IO操作有延迟 | 需要持久化的数据 |
| URL传参 | 无需额外存储 | 有大小限制 | 简单数据传递 |
最佳实践建议
- 对于小于50KB的数据,优先使用方案三(URL传参)
- 对于频繁访问的中间数据,使用方案一(全局数据总线)
- 对于需要持久化的数据,使用方案二(Preferences)
- 大数据量(>100KB)考虑使用分布式数据对象
常见问题排查
- 数据格式错误:确保所有自定义类都实现了序列化接口
- 内存泄漏:全局数据总线中的数据要及时清理
- 编码问题:URL传参时注意encode/decode的对称使用
扩展思考
对于跨设备数据共享,可以结合鸿蒙的分布式能力:
// 创建分布式数据对象
import distributedObject from '@ohos.data.distributedDataObject';
let g_object = distributedObject.createDistributedObject({data: null});
// 设置数据
g_object.data = complexData;
g_object.setSessionId('default');
更多推荐




所有评论(0)