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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/14739.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型

【大模型部署】在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型 前言 今天来写一个简单的ernie-c#的例子&#xff0c;主要参考了百度智能云的例子&#xff0c;然后自己改了改&#xff0c;学习了ERNIE模型的鉴权方式&#xff0c;数据流的格式和简单的数据解析&#xff0c;实…

软件安装:Linux安装Nginx

软件安装&#xff1a;Linux如何安装软件&#xff0c;程序。 源码安装 类似于.exe 源码包就是一堆源代码程序组成的。 linux tar.gz 这个就是源码包 源码包--------二进制包&#xff0c;源码包里面的代码经过编译之后形成的包。 优点&#xff1a;1、开源&#xff0c;可以二次…

面试八股之MySQL篇1——慢查询定位篇

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…

JavaScript 数组方法总结

JavaScript 数组方法总结 创建数组访问和修改数组&#xff08;长度 &#xff06; 元素&#xff09;添加和删除元素数组遍历元素查找过滤和映射归并和缩减数组的连接数组的扁平化数组的排序数组的反转数组的复制数组的测试数组的填充 创建数组 Array.of(...elements): 创建一个…

Singer模型与CT模型状态转移矩阵的求解

Singer模型与CT模型状态转移矩阵的求解 文章目录 Singer模型与CT模型状态转移矩阵的求解前言状态方程矩阵指数函数泰勒展开拉普拉斯变换 Singer模型CT模型 前言 回想起来&#xff0c;第一次接触Singer模型与CT模型时的状态转移矩阵时&#xff0c;对求解过程一知半解。现在&…

linux 上除了shell、python脚本以外,还有什么脚本语言用得比较多?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「 Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;说到在 Linux下的编程&#xf…

柯桥成人商务英语“​cold”是“冷”,“shoulder”是“肩膀”,​cold shoulder可不是冷肩膀!

英文中有很多俚语&#xff08;idioms&#xff09;都与身体部位有关&#xff0c;非常有趣。 今天&#xff0c;英语君就为大家介绍一些和身体部位有关的俚语&#xff0c;一起来看看吧&#xff01; cold shoulder “cold shoulder”不能用字面意思理解为“冷肩膀”&#xff0c;我们…

学习毛概思想(自用)

一、单项选择题 毛泽东思想的主要创立者是&#xff08; A &#xff09; A、毛泽东 B、刘少奇 C、周恩来 D、朱德中国共产党内第一个提出“毛泽东思想”科学概念的是&#xff08; D  &#xff09;    A、周恩来   B、刘少奇   C、朱德…

CommonJS 和 ESM 在模块加载和处理依赖关系的方式上的不同点理解

模块加载&#xff1a; CommonJS&#xff1a;当执行到 require() 函数时&#xff0c;Node.js 会同步地加载模块文件&#xff0c;即立即读取模块文件并执行其中的代码&#xff0c;然后返回模块的导出值。这就意味着&#xff0c;直到运行时我们才知道具体导入了哪些模块&#xff0…

智慧校园学工管理系统的部署

学工体系思政服务该怎么规划建造&#xff1f;思政作为高校育人的中心使命&#xff0c;在做到让学生健康高兴生长的一起&#xff0c;也应满意学生生长成才的各类需求。使用技术为学生供给优质的信息化服务&#xff0c;是其间的有效途径。大数据让个性化教育成为可能&#xff0c;…

【题解】AB33 相差不超过k的最多数(排序 + 滑动窗口)

https://www.nowcoder.com/practice/562630ca90ac40ce89443c91060574c6?tpId308&tqId40490&ru/exam/oj 排序 滑动窗口 #include <iostream> #include <vector> #include <algorithm> using namespace std;int main() {int n, k;cin >> n &…

css中弹性布局使用方法

最近写企业家用到许多弹性&#xff0c;感觉到弹性的重要性&#xff0c;今天给大家总结一下 弹性布局&#xff08;Flexbox&#xff09;是一种在 CSS 中用来实现灵活的布局方式&#xff0c;它能够方便地调整容器中子元素的尺寸、顺序和对齐方式。以下是一些常见的弹性布局属性及…

【探索数据结构】线性表之顺序表

&#x1f389;&#x1f389;&#x1f389;欢迎莅临我的博客空间&#xff0c;我是池央&#xff0c;一个对C和数据结构怀有无限热忱的探索者。&#x1f64c; &#x1f338;&#x1f338;&#x1f338;这里是我分享C/C编程、数据结构应用的乐园✨ &#x1f388;&#x1f388;&…

Vue3按顺序调用新增和查询接口

Vue3按顺序调用新增和查询接口 一、前言1、代码 一、前言 如果你想将两个调用接口的操作封装在不同的方法中&#xff0c;你可以考虑将这两个方法分别定义为异步函数&#xff0c;并在需要时依次调用它们。以下是一个示例代码&#xff1a; 1、代码 <template><div>…

丰田精益生产的模板

丰田精益生产&#xff0c;也被称为丰田生产方式&#xff08;Toyota Production System, TPS&#xff09;&#xff0c;是一套完整的生产和管理系统&#xff0c;其核心目标是最大化效率、消除浪费&#xff0c;并通过持续改进来提升产品质量。 学习优秀企业 学习福特 丰田精益生产…

C语言之函数指针(持续更新)

C语言精髓是指针&#xff0c;指针知识深似海&#xff0c;遇到一些学习一些~ 文章目录 1. typedef 定义函数指针类型2. void* 空指针的解引用 1. typedef 定义函数指针类型 函数参数化是指通过函数指针将函数的某些行为参数化。这样&#xff0c;我们可以在调用函数时动态地指定…

【每日刷题】Day48

【每日刷题】Day48 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 872. 叶子相似的树 - 力扣&#xff08;LeetCode&#xff09; 2. 114. 二叉树展开为链表 - 力扣&…

react中怎么为props设置默认值

在React中&#xff0c;你可以使用ES6的类属性&#xff08;class properties&#xff09;或者函数组件中的默认参数&#xff08;default parameters&#xff09;来定义props的默认值。 1.类组件中定义默认props 对于类组件&#xff0c;你可以在组件内部使用defaultProps属性来…

如何撰写EI会议的投稿信?

撰写EI会议的投稿信&#xff08;Cover Letter&#xff09;是向会议组织者介绍你的论文和研究工作的一个重要环节。以下是撰写投稿信的一些关键步骤和建议&#xff1a; 投稿信的结构 信头 你的信息&#xff1a;包括姓名、职位、单位名称、通讯地址、电子邮件和电话号码。日期&am…