之前的WebP动画存在以下问题:
- 不从头播放: 动画不会重置到第一帧
- 重复播放: 可能播放多次或重叠播放
- 状态管理: 动画状态管理不准确
创建了ImprovedWebPAnimationView类,主要改进:
- 重新加载机制: 每次播放前重新创建drawable实例
- 回调管理: 使用WeakReference避免内存泄漏
- 状态控制: 严格的播放状态管理
- 防重复播放: 播放前检查并停止当前动画
private fun reloadAnimation() {
// 停止当前动画
animationDrawable?.stop()
// 重新创建drawable实例
val newDrawable = ContextCompat.getDrawable(context, R.drawable.analyze)
if (newDrawable is AnimatedImageDrawable) {
animationDrawable = newDrawable
setImageDrawable(newDrawable)
}
}fun startAnimation() {
if (isAnimating) {
Log.d(TAG, "动画正在播放,先停止")
forceStopAnimation()
}
// ... 开始新的播放
}private class AnimationEndCallback(view: ImprovedWebPAnimationView) :
android.graphics.drawable.Animatable2.AnimationCallback() {
private val viewRef = WeakReference(view)
override fun onAnimationEnd(drawable: Drawable?) {
viewRef.get()?.onAnimationCompleted()
}
}添加了播放状态检查:
private fun startCaptureAnimation() {
val webpAnimation = cameraUiContainerBinding?.webpAnimation
if (webpAnimation?.isPlaying() == true) {
Log.d(TAG, "WebP动画已在播放中,跳过")
return
}
webpAnimation?.startAnimation()
}-
开始播放:
- 检查当前状态
- 停止正在播放的动画
- 重新加载drawable
- 注册回调
- 开始播放
-
播放完成:
- 回调触发
- 自动停止并隐藏
- 清理状态
-
手动停止:
- 立即停止播放
- 隐藏View
- 清理回调
- 使用WeakReference避免内存泄漏
- 在onDetachedFromWindow中清理资源
- 及时注销动画回调
- API 28+: 使用AnimatedImageDrawable
- 低版本: 降级为静态图片显示
- 错误处理: 完整的异常捕获
修复后的动画效果:
- ✅ 每次都从第一帧开始播放
- ✅ 不会重复或重叠播放
- ✅ 播放完成后自动停止
- ✅ 状态管理准确
- ✅ 内存使用优化
- 连续拍照: 快速连续点击拍照,确保动画不重叠
- 长时间使用: 测试内存是否稳定
- 不同设备: 在不同Android版本设备上测试
- 旋转屏幕: 测试横竖屏切换时的表现
# 查看动画相关日志
adb logcat | grep -E "(ImprovedWebPAnimation|WebPAnimationView)"
# 查看播放状态
adb logcat | grep "动画播放"如果新版本有问题,可以回滚到原版本:
- 在布局文件中将
ImprovedWebPAnimationView改回WebPAnimationView - 删除
ImprovedWebPAnimationView.kt文件 - 重新构建应用
ImprovedWebPAnimationView.kt- 改进的动画播放器
camera_ui_container.xml- 使用新的动画Viewcamera_ui_container.xml(横屏) - 使用新的动画ViewCameraFragment.kt- 添加防重复播放保护WebPAnimationView.kt- 修复API调用问题
WebPAnimationView.kt- 作为备用方案保留
现在WebP动画应该能正确地从头播放,且不会重复播放了!🎉