目录

应用在使用过程中持续出现闪退

问题现象

应用在使用过程中,频繁上下滑动列表导致闪退。

背景知识

问题定位

  1. 查看faultlogger目录下应用的Appfreeze日志,当前执行的任务是vSyncTask绘制任务,开始执行的时间是08:06:44.719,任务执行到08:06:51.671还未结束,执行时间超过7s,任务执行时间过长导致应用卡死。
    Fault time:2025/07/05-08:06:51
    User input does not respond!
    mainHandler dump is:
     EventHandler dump begin curTime: 2025-07-05 08:06:51.671
     Event runner (Thread name = , Thread ID = 29310) is running
     Current Running: start at 2025-07-05 08:06:44.720, Event { send thread = 29310, send time = 2025-07-05 08:06:44.719, handle time = 2025-07-05 08:06:44.719, trigger time = 2025-07-05 08:06:44.719, task name = vSyncTask, caller = [event_queue.cpp(HandleFileDescriptorEvent:280)] }
     History event queue information:
  2. 搜索关键字TID:进程ID(PID),可以获取应用栈信息。08:06:52:99应用主线程在执行initialRender任务,和页面渲染有关。
    Timestamp:2025-07-05 08:06:52:99
    Tid:29310, Name:com.hx.example
    #00 pc 0000000000447434 /system/lib64/module/arkcompiler/stub.an(RTStub_CallGetter+320)
    #01 at anonymous (entry|common|1.0.0|src/main/ets/components/BillComponent.ts:370:1)
    #02 at updateFunc (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:9157:1)
    #03 at observeComponentCreation2 (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:9177:1)
    #04 at anonymous (entry|common|1.0.0|src/main/ets/components/BillComponent.ts:368:1)
    #05 at ifElseBranchUpdateFunction (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:4300:1)
    #06 at anonymous (entry|common|1.0.0|src/main/ets/components/BillComponent.ts:367:1)
    #07 at updateFunc (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:9157:1)
    #08 at observeComponentCreation2 (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:9177:1)
    #09 at anonymous (entry|common|1.0.0|src/main/ets/components/BillComponent.ts:337:1)
    #10 at ifElseBranchUpdateFunction (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:4300:1)
    #11 at anonymous (entry|common|1.0.0|src/main/ets/components/BillComponent.ts:280:1)
    #12 at updateFunc (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:9157:1)
    #13 at observeComponentCreation2 (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:9177:1)
    #14 at initialRender (entry|common|1.0.0|src/main/ets/components/BillComponent.ts:45:1)
  3. 使用HiSmartPerf工具抓取该过程的Trace信息,从Duration可以看出preload任务执行时间达到9s。
  4. 框选主线程29310中preload任务所在的泳道,其中绝大部分时间都在执行MeasureListItem节点布局任务。过滤MeasureListItem任务,节点布局任务执行总时长达到6.8s,任务数量达到823个。

  5. 部分节点布局复杂,布局时间达到525ms,且节点数量过多,结合ListItem的使用场景可知应用在加载列表项时没有采用懒加载的方式。

分析结论

页面布局复杂并且长列表未采用懒加载导致应用卡死。

修改建议

使用懒加载优化长列表加载速度,参考文档长列表加载。

interface DataChangeListener {
  onDataReloaded(): void;

  onDataAdd(index: number): void;

  onDataDelete(index: number): void;

  onDataChange(index: number): void;
}

export class MyDataSource {
  private _data: string[] = [];
  private _listeners: DataChangeListener[] = [];

  pushData(item: string): void {
    this._data.push(item);
    this._listeners.forEach(listener => {
      listener.onDataAdd(this._data.length - 1);
    });
  }

  getAllData(): string[] {
    return this._data;
  }

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

  getData(index: number): string {
    return this._data[index];
  }

  registerDataChangeListener(listener: DataChangeListener): void {
    this._listeners.push(listener);
  }

  unregisterDataChangeListener(listener: DataChangeListener): void {
    const index = this._listeners.indexOf(listener);
    if (index !== -1) {
      this._listeners.splice(index, 1);
    }
  }
}

@Entry
@Component
struct MyComponent {
  private data: MyDataSource = new MyDataSource();

  aboutToAppear() {
    for (let i = 0; i <= 100; i++) {
      this.data.pushData(`Hello ${i}`);
    }
  }

  build() {
    List({ space: 3 }) {
      LazyForEach(this.data, (item: string) => {
        ListItem() {
          Row() {
            Text(item).fontSize(50)
              .onAppear(() => {
                console.info(`appear: ${item}`);
              });
          }.margin({ left: 10, right: 10 });
        };
      }, (item: string) => item);
    }.cachedCount(5);
  }
}