帧动画播放出现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

相关文章

2024.6.24 IDEA中文乱码问题(服务器 控制台 TOMcat)实测已解决

1.问题产生原因: 1.文件编码不一致:如果文件的编码方式与IDEA设置的编码方式不一致,就会产生乱码。确保文件和IDEA使用相同的编码,通常是UTF-8。2.IDEA设置问题:检查IDEA的全局编码设置和项目编码设置是否正确。3.终端或控制台编码问题:如果你在终端或控制台看到乱码,可能是终端的编码设置问题。确保终端使用的是支持你的文件的编码方式。 2.解决方案: 1.File -> S

[职场] 公务员的利弊分析 #知识分享#经验分享#其他

公务员的利弊分析     公务员作为一种稳定的职业选择,一直备受人们的关注。然而,就像任何其他职业一样,公务员职位也有其利与弊。本文将对公务员的利弊进行分析,帮助读者更好地了解这一职业的特点。 利: 1. 稳定的职业:公务员职位通常具有较高的稳定性,一旦进入公务员队伍,往往可以享受到稳定的工作环境和薪资待遇。这对于那些追求稳定的人来说,是一个很大的优势。 2. 薪资福利优厚:公务员的薪资和

vue同页面多路由懒加载-及可能存在问题的解决方式

先上图,再解释 图一是多路由页面,图二是路由文件。从图一可以看出每个router-view对应的name都不一样。从图二可以看出层路由对应的组件加载方式要跟图一中的name相对应,并且图二的路由层在跟图一对应的页面中要加上components层,多一个s结尾,里面的的方法名就是图一路由的name值,里面还可以照样用懒加载的方式。 页面上其他的路由在路由文件中也跟图二是一样的写法。 附送可能存在

vue+elementui分页输入框回车与页面中@keyup.enter事件冲突解决

解决这个问题的思路只要判断事件源是哪个就好。el分页的回车触发事件是在按下时,抬起并不会再触发。而keyup.enter事件是在抬起时触发。 so,找不到分页的回车事件那就拿keyup.enter事件搞事情。只要判断这个抬起事件的$event中的锚点样式判断不等于分页特有的样式就可以了 @keyup.enter="allKeyup($event)" //页面上的//js中allKeyup(e

vue+elementui--$message提示框被dialog遮罩层挡住问题解决

最近碰到一个先执行this.$message提示内容,然后接着弹出dialog带遮罩层弹框。那么问题来了,message提示框会默认被dialog遮罩层挡住,现在就是要解决这个问题。 由于都是弹框,问题肯定是出在z-index比重问题。由于用$message方式是写在js中而不是写在html中所以不是很好直接去改样式。 不过好在message组件中提供了customClass 属性,我们可以利用

高度内卷下,企业如何通过VOC(客户之声)做好竞争分析?

VOC,即客户之声,是一种通过收集和分析客户反馈、需求和期望,来洞察市场趋势和竞争对手动态的方法。在高度内卷的市场环境下,VOC不仅能够帮助企业了解客户的真实需求,还能为企业提供宝贵的竞争情报,助力企业在竞争中占据有利地位。 那么,企业该如何通过VOC(客户之声)做好竞争分析呢?深圳天行健企业管理咨询公司解析如下: 首先,要建立完善的VOC收集机制。这包括通过线上渠道(如社交媒体、官网留言

Docker启动异常

报错信息: failed to start daemon: Error initializing network controller: error creating default "bridge" network: cannot create network b8fd8c684f0ba865d4a13d36e5282fd694bbd37b243c7ec6c9cd29416db98d4b (d

Pycharm配置conda环境(解决新版本无法识别可执行文件问题)

引言: 很多小伙伴在下载最新版本的pycharm或者更新到最新版本后为项目配置conda环境的时候,发现文件夹目录中无法显示可执行文件(一般为python.exe),以下就是本人遇到该问题后试验和解决该问题的一些方法和思路。 一般遇到该问题的人群有两种,一种是刚入门对pycharm进行conda环境配置的小白(例如我),不熟悉相关环境配置的操作和过程,还有一种是入坑pycharm有段时间的老手

青龙面板之Ninja无法安装无法拉库问题解决

因为之前的Ninja库已经不能用了,甚至新找到的库也不能用了,好尴尬,这里使用线下版本进行安装。 ninja安装新方法,其是方法还是原来的,只不过Ninja的库原作者删了,没法直接git了,但是我找到了源码包,我们可以直接通过宝塔面板拖进去。 源码包地址: https://download.csdn.net/download/u012134073/24813485 备用地址: 链接: h

tomcat端口被占用如何解决

转载:https://www.cnblogs.com/demon09/p/9248445.html