积分584 / 贡献0

提问0答案被采纳0文章51

[经验分享] 相册应用崩溃问题分析报告 原创 精华

Laval社区小助手 显示全部楼层 发表于 2024-3-14 09:41:16

1 关键字

相册源码;新建相册;全部删除;全部还原;应用崩溃

2 问题描述

开发板型号:rk3568

OH版本:OpenHarmony 3.1 Release

问题现象:在rk3568开发板上运行相册应用,新建一个相册,选择7个视频和照片,打开新建相册,全部删除,打开最近删除,还原全部,应用返回相册集页面后,相册应用高概率闪退,跳回桌面。

测试步骤:

1.新建相册,选择7个视频和照片

2.打开新建相册,全部删除

3.打开最近删除,全部还原

相册应用高概率闪退,跳回桌面。

3 问题原因

3.1 正常机制

相册在最近删除中执行全部还原操作后,自动返回相册集页面,相册集页面LazyForEach懒加载被改变的相册的相册名、相片总数量、相册封面缩略图正常渲染、展示。

3.2 异常机制

相册在最近删除中执行全部还原操作后,自动返回相册集页面,相册集页面的LazyForEach懒加载了被改变相册的相册名、相片总数量,但是在使用相册封面图片在媒体库的地址this.item.coverUri,根据Image(this.item.coverUri)渲染相册封面缩略图时,加载失败,导致应用闪退回桌面。

4 解决方案

通过下面的方式,可以解决此崩溃问题,在相册集的LazyForEach加载被改变的相册的缩略图时,使用sdk自带的获取缩略图的方法获取相册封面缩略图展示封面,就发生加载失败的情况。

4.1 修改相册源码文件AlbumInfo.ets

在AlbumInfo.ets中添加新属性:pixelMap:any。目的是为了存放新方式获取的相册封面缩略图。

4.2 修改相册源码文件AlbumDataImpl.ets

修改此文件中获取相册封面信息的所有方法,各添加一行获取缩略图的代码

1.AlbumDataImpl.ets中的getVirtualAlbum方法的let data = new AlbumInfo(this.getThumbnailSafe(file.obj.uri),name, this.getAlbumDisplayName(name), file.count, this.deviceId);的下面添加一行代码:data.pixelMap = await file.obj.getThumbnail();
2.在AlbumInfo.ets的getFavorAlbum方法的let fav = new AlbumInfo(await this.getThumbnailSafe(favAlbum.file.uri), AlbumDefine.ALBUM_NAME_FAVOR, this.getAlbumDisplayName(AlbumDefine.ALBUM_NAME_FAVOR), favAlbum.count, this.deviceId);的下面添加一行代码:fav.pixelMap = await favAlbum.file.getThumbnail();
3.在AlbumInfo.ets的getEntityAlbumSourceData方法的let album = new AlbumInfo(this.getThumbnailSafe(obj.uri),item.albumName, item.albumName, count, this.deviceId);的下面添加一行代码:album.pixelMap = await obj.getThumbnail();
4.在AlbumInfo.ets的getTrashAlbum方法的let trash = new AlbumInfo(await this.getThumbnailSafe(trashAlbum.file.uri), AlbumDefine.ALBUM_NAME_RECYCLE,this.getAlbumDisplayName(AlbumDefine.ALBUM_NAME_RECYCLE), trashAlbum.count, this.deviceId);的下面添加一行代码:trash.pixelMap = await trashAlbum.file.getThumbnail();

4.3 修改相册源码AlbumGridItemNewStyle.ets

修改相册集页面渲染相册封面缩略图的代码

将AlbumGridItemNewStyle.ets中的Image(this.item.coverUri)都改为:Image(this.item.pixelMap)

按照以上步骤修改代码之后,相册集页面可以正常显示,不再崩溃。

5 定位过程

1.刚开始根据客户提供的崩溃日志,找到几个关键的ets文件,梳理了相册集的相册是如何渲染的,发现绘制相册的数据是:相册名、相册照片总数量、相册封面缩略图,在关键代码处打日志,然后根据原场景复测,发现相册集的各个相册的渲染数据是获取到了,并非空,于是跟踪单个相册绘制的ets日志,发现在渲染相册封面缩略图的时候,使用Image(this.item.coverUri)渲染封面,其中coverUri是从媒体库拿到的相册封面图片的媒体库地址,但是在后面多拼接了"/thumbnail/256/256",于是猜测可能是因为拼接后面这段后缀,导致从媒体库拿资源的时候,出现无法获取到的情况发生。

08-08 10:12:35.257  1906  1906 I 02200/JsApp: Photos_zhaop AlbumSetDataSource: totalCount: 3
08-08 10:12:35.258  1906  1906 I 02200/JsApp: Photos_zhaop AlbumSetDataSource: getData index: 0, item: {"id":"2","coverUri":"dataability:///media/image/11/thumbnail/256/256","name":"Camera","displayName":"","count":9,"isDisabl
eRename":true,"isDisableDelete":true,"videoCount":0,"deviceId":"","relativePath":"Pictures/Camera/","coverOrientation":0,"uri":"dataability:///media/album/2","deviceName":"","innerId":"default_camera"}
08-08 10:12:35.259  1906  1906 I 02200/JsApp: zhaop AlbumGridItemNewStyle this.item: []
08-08 10:12:35.259  1906  1906 I 02200/JsApp: Photos_Album_zhaop AlbumGridItemNewStyle: zhaop Album changed and update card size strat
08-08 10:12:35.261  1906  1906 I 02200/JsApp: Photos_Album_zhaop AlbumGridItemNewStyle: zhaop Album changed and update card size end
08-08 10:12:35.276  1906  1906 I 02200/JsApp: Photos_zhaop AlbumSetDataSource: getData index: 1, item: {"id":"default_all","coverUri":"dataability:///media/image/20/thumbnail/256/256","name":"default_all","displayName":"",count":17,"isDisableRename":true,"isDisableDelete":true,"videoCount":0,"deviceId":"","relativePath":"","coverOrientation":0,"deviceName":"","innerId":"default_all"}
08-08 10:12:35.277  1906  1906 I 02200/JsApp: zhaop AlbumGridItemNewStyle this.item: []
08-08 10:12:35.278  1906  1906 I 02200/JsApp: Photos_Album_zhaop AlbumGridItemNewStyle: zhaop Album changed and update card size strat
08-08 10:12:35.279  1906  1906 I 02200/JsApp: Photos_Album_zhaop AlbumGridItemNewStyle: zhaop Album changed and update card size end
08-08 10:12:35.294  1906  1906 I 02200/JsApp: Photos_zhaop AlbumSetDataSource: totalCount: 3
08-08 10:12:35.305  1906  1906 I 02200/JsApp: Photos_zhaop AlbumSetDataSource: getData index: 2, item: {"id":"12","coverUri":"dataability:///media/image/20/thumbnail/256/256","name":"newAlbum1","displayName":"","count":8,"i
sDisableRename":false,"isDisableDelete":false,"videoCount":0,"deviceId":"","relativePath":"Pictures/newAlbum1/","coverOrientation":0,"uri":"dataability:///media/album/12","deviceName":"","innerId":"12"}
08-08 10:12:35.383  1906  1906 I 02200/JsApp: zhaop AlbumGridItemNewStyle Image: id "12" and coverUri:dataability:///media/image/20/thumbnail/256/256

2.猜测点已找到,于是将相册封面缩略图改成了工程media目录下的固定图片,进行复测,结果不再崩溃。得出结果就是封面缩略图的地址有问题,于是查找源码,发现源码中有特定获取缩略图的方法,用该方法返回值替换coverUri来渲染相册封面缩略图。

6 知识分享

  • 相册应用中相册集页面的每个相册的封面加载的是每个相册第一张照片的缩略图。
  • 获取照片缩略图建议使用接口FileAsset中的getThumbnail()方法。声明文件为:@ohos.multimedia.mediaLibrary.d.ts,源码提供了相关api,尽量用源码api解决问题。
无用

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部