开发者工具箱-鸿蒙懒加载功能开发笔记

2025-06-04 12:59:43
108次阅读
0个评论

鸿蒙懒加载功能开发笔记

前言

最近在开发鸿蒙应用的时候,发现数据加载的效率问题一直是个头疼的问题。为了提升用户体验,我决定使用懒加载技术,确保数据在需要时才被加载。下面分享一下我的开发心得。

功能说明

懒加载的主要功能如下:

  • 按需加载数据
  • 提高应用性能
  • 减少内存占用

实现过程

故事一:懒加载的崩溃风波

记得刚开始写这个功能的时候,我直接用了系统自带的懒加载模块,心想:"这不就是调用个API的事嘛,简单!"结果各种问题接踵而至。最搞笑的是有个用户点击加载按钮,程序直接崩溃了。用户一看就炸了:"这什么鬼?我要的是友好的错误提示!"我心想:"不就是个错误提示嘛,简单!"结果一上手才发现,得加try-catch,还得给出具体的错误信息,真是让人头大。最后改了好几版,加了个加载动画,这才好多了。

// 示例代码:懒加载
class LazyLoader<T> {
  private dataSource: IDataSource<T>;

  constructor(dataSource: IDataSource<T>) {
    this.dataSource = dataSource;
  }

  loadData(index: number): T {
    return this.dataSource.getData(index);
  }
}

故事二:数据变化的尴尬时刻

还有一次,有个用户说数据变化功能不好用,我一开始还觉得挺委屈:"这不是挺简单的吗?"结果自己试了一下,发现确实有点问题。最尴尬的是,数据变化的时候没有提示,而且有时候会加载失败。用户反馈说:"加载了半天,结果不知道加载成功没有,气死我了!"我赶紧改了好几版,加了个加载成功的提示,这才好多了。现在想想,真是感谢那位用户的反馈,要不然我还真发现不了这个问题。

// 示例代码:数据变化监听
class DataChangeListener {
  onDataReloaded(): void {}
  onDataAdded(index: number): void {}
  onDataMoved(from: number, to: number): void {}
  onDataDeleted(index: number): void {}
  onDataChanged(index: number): void {}
}

使用场景

  1. 按需加载:用户可以通过点击按钮按需加载数据,提升应用性能。
  2. 数据变化:用户可以监听数据变化,及时更新界面。
  3. 用户反馈:通过提示信息,用户可以及时了解操作结果。

踩坑记录

  1. 懒加载时,有时候会遇到内存问题(有时候一不小心就OOM了,真服了)
  2. 数据变化时,有时候弹窗都不弹,气死个人
  3. 用户反馈时,有时候会莫名其妙弹个错,真服了

完整示例

下面是我实际开发中用的代码,大家可以参考一下:

// 1. 首先定义数据源接口
interface IDataSource<T> {
  totalCount(): number;
  getData(index: number): T;
  registerDataChangeListener(listener: DataChangeListener): void;
  unregisterDataChangeListener(listener: DataChangeListener): void;
}

// 2. 定义数据变化监听器
class DataChangeListener {
  onDataReloaded(): void {}
  onDataAdded(index: number): void {}
  onDataMoved(from: number, to: number): void {}
  onDataDeleted(index: number): void {}
  onDataChanged(index: number): void {}
}

// 3. 实现基础数据源类
@Observed
class BasicDataSource<T> implements IDataSource<T> {
  private listeners: DataChangeListener[] = [];
  protected dataArray: T[] = [];

  public totalCount(): number {
    return this.dataArray.length;
  }

  public getData(index: number): T {
    return this.dataArray[index];
  }

  // 设置整个数据列表
  public setData(array: T[]): void {
    this.dataArray = array;
    this.notifyDataReload();
  }

  // 添加单条数据
  public addData(item: T): void {
    this.dataArray.push(item);
    this.notifyDataAdd(this.dataArray.length - 1);
  }

  // 删除单条数据
  public deleteData(index: number): void {
    this.dataArray.splice(index, 1);
    this.notifyDataDelete(index);
  }

  // 更新单条数据
  public updateData(index: number, data: T): void {
    this.dataArray[index] = data;
    this.notifyDataChange(index);
  }

  // 清空数据
  public clearData(): void {
    this.dataArray = [];
    this.notifyDataReload();
  }

  // 注册数据变化监听器
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      this.listeners.push(listener);
    }
  }

  // 注销数据变化监听器
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const index = this.listeners.indexOf(listener);
    if (index >= 0) {
      this.listeners.splice(index, 1);
    }
  }

  // 通知数据变化相关方法
  protected notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    });
  }

  protected notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdded(index);
    });
  }

  protected notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChanged(index);
    });
  }

  protected notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDeleted(index);
    });
  }

  protected notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMoved(from, to);
    });
  }
}

// 4. 使用示例
@Component
struct IconList {
  @State iconList: BasicDataSource<IconItem> = new BasicDataSource<IconItem>();
  
  build() {
    Grid() {
      LazyForEach(this.iconList, (icon: IconItem) => {
        GridItem() {
          Column() {
            Image(icon.symbol)
              .width(24)
              .height(24)
            Text(icon.name)
              .fontSize(12)
          }
        }
      }, (icon: IconItem, index: number) => {
        return icon.name + index
      })
    }
    .columnsTemplate('1fr 1fr 1fr 1fr')
    .rowsGap(8)
    .columnsGap(8)
  }
}

总结

这个懒加载功能,基本功能都齐了:

  • 支持按需加载数据
  • 支持数据变化监听
  • 提供用户反馈

说实话,开发这个功能的过程真是让我又爱又恨。爱的是看着它从无到有,一步步变得更好用;恨的是各种坑踩得我头都大了。不过现在想想,这些坑踩得值!要不是这些坑,我还真发现不了这么多可以优化的地方。

有些边角问题其实还没完全搞定,比如有时候加载还是会有点慢,数据变化的时候偶尔会卡一下(有时候还会莫名其妙弹个错,真服了)。不过大部分场景都能用,用户反馈也还不错。后面有空再慢慢优化吧,毕竟好产品都是慢慢打磨出来的。

参考资料

  • 鸿蒙开发文档
  • 懒加载技术文档

欢迎体验

如果你也在开发鸿蒙应用,欢迎使用这个功能,希望能帮到你!

作者信息

作者:在人间耕耘 邮箱:1743914721@qq.com 版权声明:本文为博主原创文章,转载请附上原文出处链接及本声明。

收藏00

登录 后评论。没有帐号? 注册 一个。