• 背景及现象

大屏gk6320芯片,首次刷机进入系统后,在设置界面点击遥控器,焦点响应迟钝,调节音量时,音量面板弹出有长达几秒的延迟,这一现象会贯穿首次启动的整个生命周期,系统重启后恢复正常。

  • 问题定界

img

分析对比调节音量正常和异常时的日志,发现当调节音量异常时,中间有连接settingsdata数据库失败和重试的打印,无异常时连接数据库是连接成功的。推测问题原因为通过datashare接口连接settingsdata数据库失败。分析wifi等同样存在卡顿现象的应用代码,发现都有读写settings的操作,并且日志中同样打印了datashare连接失败的信息。因此,操作卡顿原因大概率是因为进程阻塞在了通过datashare读写settings数据库时

img

  • 业务流程

先梳理下调节音量到datashare的调用链

img

再来看看DataShareHelper::Creator的代码(静默访问和非静默访问的概念可以参考下面的链接),由于应用指定的是静默访问方式,所以这里会首先尝试通过datashare服务静默访问数据(CreateServiceHelper),如果无法静默访问,那么就尝试非静默访问(拉起数据提供者CreateExtHelper)

静默数据共享 https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/database/share-data-by-silent-access-sys.md

非静默数据共享 https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/database/share-data-by-datashareextensionability-sys.md

img

GetSilentProxyStatus通过最终会通过IPC调用DataShareServiceImpl::GetSilentProxyStatus(),在该函数中我们看到最终是由rdb中是否存在目标元数据来判断静默访问方式是否可用的。

img

img

一旦静默访问数据失败,就会调用DataShareHelper::CreateExtHelper来拉起数据供应者(settingsdata)来提供数据访问,至此我们已基本了解访问settingsdata数据的业务流程。

  • 分析定位

img

随后从19:21:39.946到19:21:41.999 systemui返回连接数据源失败两秒多的时间内,数据管理进程distributeddata(3522)一直在反复尝试获取settingsdata元数据

img

img

等到2秒的超时时间过后,音量数据保存失败返回后才显示音量面板变化,这就是UI卡顿的根本原因。接下来问题的关键是需要找到获取settingsdata元数据失败的原因。

分析启动日志发现启动过程中有创建settingsdata.db失败的有关打印,其原因是没有找打distributed data manager服务。经确认,settingsdata在启动时会执行数据库初始化,如失败后面不再进行尝试。

img

对比日志中distributeddata服务的初始化完成时间,发现系统刷机后首次启动要比正常启动晚3~5s, 其原因是系统首次启动需处理一些额外的业务,如创建sandbox、私有数据初始化、预装应用等,这导致系统首次启动的耗时要比正常启动要长的多,显然各系统服务的启动时间点也会收到影响。同时联想到此前做系统开机速度优化是曾对distributeddata服务做个延迟启动处理:

img

因而推测此修改正好导致刷机后系统首次启动时distributeddata的启动时间超过了临界点,导致settingsdata开库时无法获取到distributeddatamgr,从而导致所有对settingsdata的静默连接超时。

尝试恢复distributed_data.cfg为原始配置文件,取消distributeddata服务的延迟启动,首次启动卡顿现象不再出现。

至此可以证实此问题根因为:distributeddate服务启动太晚导致数据库元数据创建失败,无法通过静默方式访问setttingsdata.

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐