文章目录
SVGA源码解析
数据解析-SVGAParser
主要是decodeFromInputStream方法,读取解析来自URL的svga文件,并缓存成本地文件
fun decodeFromInputStream(
inputStream: InputStream,
cacheKey: String,
callback: ParseCompletion?
) {
threadPoolExecutor.execute {
try {
readAsBytes(inputStream)?.let {
bytes ->
threadPoolExecutor.execute {
// 缓存成本地文件,这边就延伸一个问题,不会默认缓存到内存,每次都需要重新load
SVGACache.buildSvgaFile(cacheKey).let {
cacheFile ->
cacheFile.takeIf {
!it.exists() }?.createNewFile()
FileOutputStream(cacheFile).write(bytes)
}
}
// protobuf 解析成SVGAVideoEntity
inflate(bytes)?.let {
inflateBytes ->
val videoItem = SVGAVideoEntity(
MovieEntity.ADAPTER.decode(inflateBytes),
File(cacheKey),
mFrameWidth,
mFrameHeight
)
}
}
}
}
动画实体类-SVGAVideoEntity
看一下SVGAVideoEntity的属性和构造
var antiAlias = true //抗锯齿
var movieItem: MovieEntity? = null // 解析方法传进来的MovieEntity
var videoSize = SVGARect(0.0, 0.0, 0.0, 0.0) // 播放大小
private set
var FPS = 15 // 设置fps,帧率
private set
var frames: Int = 0 //frame的个数
private set
internal var spriteList: List<SVGAVideoSpriteEntity> = emptyList() // 每一帧的信息集合
internal var imageMap = HashMap<String, Bitmap>() // Bitmap缓存,每一帧绘制可以重复利用
constructor(entity: MovieEntity, cacheDir: File, frameWidth: Int, frameHeight: Int) {
this.mFrameWidth = frameWidth
this.mFrameHeight = frameHeight
this.mCacheDir = cacheDir
this.movieItem = entity
entity.params?.let(this::setupByMovie)
try {
// 解析图片并且缓存到map中
parserImages(entity)
} catch (e: Exception) {
e.printStackTrace()