帧动画播放出现oom异常分析及解决

2024-05-25 00:28

本文主要是介绍帧动画播放出现oom异常分析及解决,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题描述

需要播放序列帧,帧数特别多的时候会oom

问题分析

源代码每一帧都创建一次bitmap,极度消耗内存
bitmap.recycle并不会立刻回收内存,内存还是会很紧张

问题解决

利用inbitmap,每一帧复用同一片内存区域

//设置Bitmap内存复用
mBitmapOptions.inBitmap = mBitmap;//Bitmap复用内存块,类似对象池,避免不必要的内存
// 初始化bitmap使用该参数bitmap = BitmapFactory.decodeResource(imageView.getResources(), imageRes, mBitmapOptions);

完整代码如下

    /*** 循环读取帧---循环播放帧*/public class FramesSequenceAnimation {private int[] mFrames; // 帧数组private int mIndex; // 当前帧private boolean mShouldRun; // 开始/停止播放用private boolean mIsRunning; // 动画是否正在播放,防止重复播放private SoftReference<ImageView> mSoftReferenceImageView; // 软引用ImageView,以便及时释放掉private Handler mHandler;private int mDelayMillis;private OnAnimationStoppedListener mOnAnimationStoppedListener; //播放停止监听private Bitmap mBitmap = null;private BitmapFactory.Options mBitmapOptions;//Bitmap管理类,可有效减少Bitmap的OOM问题public FramesSequenceAnimation(ImageView imageView, int[] frames, int fps) {mHandler = new Handler();mFrames = frames;mIndex = -1;mSoftReferenceImageView = new SoftReference<ImageView>(imageView);mShouldRun = false;mIsRunning = false;mDelayMillis = 1000 / fps;//帧动画时间间隔,毫秒imageView.setImageResource(mFrames[0]);// 当图片大小类型相同时进行复用,避免频繁GCif (Build.VERSION.SDK_INT >= 11) {Bitmap bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();int width = bmp.getWidth();int height = bmp.getHeight();Bitmap.Config config = bmp.getConfig();mBitmap = Bitmap.createBitmap(width, height, config);mBitmapOptions = new BitmapFactory.Options();//设置Bitmap内存复用mBitmapOptions.inBitmap = mBitmap;//Bitmap复用内存块,类似对象池,避免不必要的内存分配和回收mBitmapOptions.inMutable = true;//解码时返回可变BitmapmBitmapOptions.inSampleSize = 1;//缩放比例}}//循环读取下一帧private int getNext() {mIndex++;if (mIndex >= mFrames.length) {mIndex = 0;}return mFrames[mIndex];}/*** 播放动画,同步锁防止多线程读帧时,数据安全问题*/public synchronized void start() {mShouldRun = true;if (mIsRunning) {return;}Runnable runnable = new Runnable() {@Overridepublic void run() {ImageView imageView = mSoftReferenceImageView.get();if (!mShouldRun || imageView == null) {mIsRunning = false;if (mOnAnimationStoppedListener != null) {mOnAnimationStoppedListener.AnimationStopped();}return;}mIsRunning = true;//新开线程去读下一帧mHandler.postDelayed(this, mDelayMillis);if (imageView.isShown()) {int imageRes = getNext();if (mBitmap != null) { // so Build.VERSION.SDK_INT >= 11Bitmap bitmap = null;try {bitmap = BitmapFactory.decodeResource(imageView.getResources(), imageRes, mBitmapOptions);} catch (Exception e) {e.printStackTrace();}if (bitmap != null) {imageView.setImageBitmap(bitmap);} else {imageView.setImageResource(imageRes);mBitmap.recycle();mBitmap = null;}} else {imageView.setImageResource(imageRes);}}}};mHandler.post(runnable);}/*** 停止播放*/public synchronized void stop() {mShouldRun = false;if (mHandler != null) {mHandler.removeCallbacksAndMessages(null);}}/*** 设置停止播放监听** @param listener*/public void setOnAnimStopListener(OnAnimationStoppedListener listener) {this.mOnAnimationStoppedListener = listener;}}

这篇关于帧动画播放出现oom异常分析及解决的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/999964

相关文章

springboot3.x使用@NacosValue无法获取配置信息的解决过程

《springboot3.x使用@NacosValue无法获取配置信息的解决过程》在SpringBoot3.x中升级Nacos依赖后,使用@NacosValue无法动态获取配置,通过引入SpringC... 目录一、python问题描述二、解决方案总结一、问题描述springboot从2android.x

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

解决idea启动项目报错java: OutOfMemoryError: insufficient memory

《解决idea启动项目报错java:OutOfMemoryError:insufficientmemory》:本文主要介绍解决idea启动项目报错java:OutOfMemoryError... 目录原因:解决:总结 原因:在Java中遇到OutOfMemoryError: insufficient me

maven异常Invalid bound statement(not found)的问题解决

《maven异常Invalidboundstatement(notfound)的问题解决》本文详细介绍了Maven项目中常见的Invalidboundstatement异常及其解决方案,文中通过... 目录Maven异常:Invalid bound statement (not found) 详解问题描述可

C++ scoped_ptr 和 unique_ptr对比分析

《C++scoped_ptr和unique_ptr对比分析》本文介绍了C++中的`scoped_ptr`和`unique_ptr`,详细比较了它们的特性、使用场景以及现代C++推荐的使用`uni... 目录1. scoped_ptr基本特性主要特点2. unique_ptr基本用法3. 主要区别对比4. u

nacos服务无法注册到nacos服务中心问题及解决

《nacos服务无法注册到nacos服务中心问题及解决》本文详细描述了在Linux服务器上使用Tomcat启动Java程序时,服务无法注册到Nacos的排查过程,通过一系列排查步骤,发现问题出在Tom... 目录简介依赖异常情况排查断点调试原因解决NacosRegisterOnWar结果总结简介1、程序在

Nginx内置变量应用场景分析

《Nginx内置变量应用场景分析》Nginx内置变量速查表,涵盖请求URI、客户端信息、服务器信息、文件路径、响应与性能等类别,这篇文章给大家介绍Nginx内置变量应用场景分析,感兴趣的朋友跟随小编一... 目录1. Nginx 内置变量速查表2. 核心变量详解与应用场景3. 实际应用举例4. 注意事项Ng

Java多种文件复制方式以及效率对比分析

《Java多种文件复制方式以及效率对比分析》本文总结了Java复制文件的多种方式,包括传统的字节流、字符流、NIO系列、第三方包中的FileUtils等,并提供了不同方式的效率比较,同时,还介绍了遍历... 目录1 背景2 概述3 遍历3.1listFiles()3.2list()3.3org.codeha

Java Exception异常类的继承体系详解

《JavaException异常类的继承体系详解》Java中的异常处理机制分为异常(Exception)和错误(Error)两大类,异常分为编译时异常(CheckedException)和运行时异常... 目录1. 异常类的继承体系2. Error错误3. Exception异常3.1 编译时异常: Che