关于解决加载不规范的svga出现的oom问题解决思路
gao746700783 opened this issue · comments
问题表现
在项目上发现,找的个人制作的svga动画质量参差不齐,有些是按照帧序列动画来制作导致svga加载后内存占用极大,会导致无法避免的oom
提出一种解决思路
- 设置svga解析拦截器,10M
svgaParser.addInterceptors(new MaxSizeInterceptor(10 * 1024 *1024));
- 解析时构造预处理的SVGAVideoEntity,这个类中不存放bitmap
// 构造SVGAVideoEntity
val pre_videoItem = SVGAVideoEntity( MovieEntity.ADAPTER.decode(it), File(cacheKey), mFrameWidth, mFrameHeight ,true )
// parserImages时,先预处理
val imageInfo = FastImageInfo(byteArray) val width = imageInfo.width val height = imageInfo.height LogUtils.error(TAG,"width:$width ,height:$height") // 未经处理过的原图需要占的内存大小 preCalcSize += width * height * 4
// preHandleByInterceptors ,拦截器预处理 SVGAVideoEntity,如果 将要加载到内存中的svga过大,则拦截
`
var result: Boolean = false
if (interceptors.isNotEmpty()) {
for (itor: Interceptor in interceptors) {
result = itor.intercept(pre_videoItem)
if (result) { break }
}
}
if (result) {
pre_videoItem.prepare({
pre_videoItem.intercept = true
LogUtils.info(TAG, "SVGAVideoEntity prepare success")
this.invokeCompleteCallback(pre_videoItem, callback, alias)
}, playCallback)
LogUtils.error(TAG,"preHandle interrupt this ...")
return true
}
`
- decodeFromAssets 的 SVGAParser.ParseCompletion中进行处理
if (videoItem.getIntercept()) { Log.e("zzzz", "svga intercepted"); return; }
关键实现思路:
- 预处理,解析得出空的SVGAVideoEntity,如果未经处理过的原图需要占的内存大小 大于拦截器中定义的大小,则不要加载到内存中
- 根据svga文件的byte数据提取出 png的width ,height等
------ 中文分割线 ------
在其他issue上看到 要开发3.0版本,不知道能不能把这些内容加上?
请评估