目录

截屏操作耗时较长,多次截屏操作后出现无响应的现象

问题现象

应用具有截屏分享功能,在稳定性测试时,多次执行截屏功能应用发生AppFreeze错误。

背景知识

问题定位

  1. 查看AppFreeze日志,应用发生了APP_INPUT_BLOCK异常,搜索关键字TID:进程ID(PID),可以获取应用栈信息。

    堆栈中有takeScreenShot字段,说明应用有对截屏事件做特殊处理。

    EVENTNAME = APP_INPUT_BLOCK
    TIMESTAMP = 2025/05/10-13:32:09:970
    PID = 16610
    UID = 20020195
    TID = 16610
    PACKAGE_NAME = com.hx.example
    PROCESS_NAME = com.hx.example
    eventLog_action = ffrt,t:input,t,cmd:c,cmd:dam,tr,k:SysRqFile,cmd:m
    eventLog_interval = 10
    MSG = 
    Fault time:2025/05/10-13:32:05
    User input does not respond!
    Timestamp:2025-05-10 13:32:06:52
    Tid:16610, Name:com.hx.example
    #00 pc 0000000000f348bc /system/lib64/libskia_canvaskit.z.so(neon::matrix_scale_translate(unsigned long, void**, unsigned long, unsigned long, float vector[4], float vector[4], float vector[4], float vector[4], float vector[4], float vector[4], float vector[4], float vector[4])+24)(41c7e50437de39b1aaa05208f048d2dd)
    #01 pc 0000000000f77a64 /system/lib64/libskia_canvaskit.z.so(neon::start_pipeline(unsigned long, unsigned long, unsigned long, unsigned long, void**)+4496)(41c7e50437de39b1aaa05208f048d2dd)
    #02 pc 00000000011281f4 /system/lib64/libskia_canvaskit.z.so(SkRasterPipelineBlitter::blitRect(int, int, int, int)+712)(41c7e50437de39b1aaa05208f048d2dd)
    #03 pc 0000000000f2e33c /system/lib64/libskia_canvaskit.z.so(SkScan::FillRect(SkRect const&, SkRasterClip const&, SkBlitter*)+140)(41c7e50437de39b1aaa05208f048d2dd)
    #04 pc 0000000000f2d998 /system/lib64/libskia_canvaskit.z.so(SkDraw::drawRect(SkRect const&, SkPaint const&, SkMatrix const*, SkRect const*) const+1160)(41c7e50437de39b1aaa05208f048d2dd)
    #05 pc 0000000000f2cec0 /system/lib64/libskia_canvaskit.z.so(SkDraw::drawBitmap(SkBitmap const&, SkMatrix const&, SkRect const*, SkSamplingOptions const&, SkPaint const&) const+964)(41c7e50437de39b1aaa05208f048d2dd)
    // ...
    #21 at takeScreenShot (entry|@lk/lk_oh_fitness_others|1.0.1|src/main/ets/pageshowaspect/help/ScreenShotHelper.ts:19:1)
  2. 由于稳定性测试中会进行频繁的截屏操作,所以需要排查是否截屏事件过多,执行时间过长导致AppFreeze。
  3. 搜索关键字"catcher cmd: hilog -z 1000 -P ",可以看到hilog日志中截屏时间频繁。
    05-10 13:31:46.629 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:46.630 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:46.631 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:49.286 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:49.287 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:50.011 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:50.012 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:54.765 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:54.767 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:55.507 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
    05-10 13:31:55.509 16610 16610 I A03D00/com.hx.example/JSAPP: screenshot happenedundefined
  4. 使用HiSmartPerf工具抓取该过程的Trace信息,在连续截屏的情况下,单个业务执行时间平均0.85s(见顶部时间轴),累计就导致了主线程阻塞。

分析结论

应用监听截屏事件,执行相应业务耗时较长,稳定性测试多次截屏时导致主线程卡死。

修改建议

优化耗时,当主线程中遇到一些难以避免的耗时操作时,例如同步网络请求、大文件读写、复杂计算、音频处理、数据传输等,可以从以下角度进行性能优化:

控制执行次数,当遇到用户高频事件输入时,根据业务场景,可以选择节流、防抖或限制次数的方式进行优化: