Android帧动画一次性加载会造成ui卡顿,所以就有了这份代码。通过handle队列和Bitmap复用,每次加载一张并显示,可以解决帧动画卡顿问题。

使用方法:

int[] right_res_id = new int[]{R.drawable.r_00072, R.drawable.r_00073, R.drawable.r_00074, R.drawable.r_00075};final AnimationsContainer.FramesSequenceAnimation rightAnim =AnimationsContainer.getInstance().createProgressDialogAnim(imgRight,right_res_id);rightAnim.setOnAnimStopListener(new AnimationsContainer.OnAnimationListener() {@Overridepublic void onAnimationStart(AnimationsContainer.FramesSequenceAnimation animation) {//TODO}@Overridepublic void onAnimationEnd(AnimationsContainer.FramesSequenceAnimation animation) {//TODO}@Overridepublic void onAnimationStopOrCancel(AnimationsContainer.FramesSequenceAnimation animation) {//TODO}});
//rightAnim.setLoop(true);
//rightAnim.setGoBack(true); //只有动画停止时才会调用
//rightAnim.setDelayMillis(58); //设置每帧播放时间,与setDuration(long)二选一
rightAnim.setDuration(3000); //设置播放总时间
rightAnim.start();//rightAnim.stop();
//rightAnim.goBackStart(); //返回第一帧//rightAnim.cancel();

代码AnimationsContainer.java

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.os.Handler;
import android.widget.ImageView;import java.lang.ref.SoftReference;/*** 帧动画加载工具类*/public class AnimationsContainer {private static final AnimationsContainer mInstance = new AnimationsContainer();private AnimationsContainer() {}/*** 获取单例*/public static AnimationsContainer getInstance() {return mInstance;}/*** 创建一个 Imageview 的播放动画类** @param imageView 要播放动画的ImageView* @param resId     资源id数组* @return progress dialog animation*/public FramesSequenceAnimation createProgressDialogAnim(ImageView imageView, int[] resId) {return new FramesSequenceAnimation(imageView, resId);}/*** 循环读取帧---循环播放帧*/public class FramesSequenceAnimation {private int[] mFrames; // 帧数组private int mIndex; // 当前帧private boolean mShouldRun; // 开始/停止播放用private boolean mIsRunning; // 动画是否正在播放,防止重复播放private SoftReference<ImageView> mSoftReferenceImageView; // 软引用ImageView,以便及时释放掉private Handler mHandler;private long mDelayMillis = 58;private boolean isLoop = false;private boolean isGoBack = true;private OnAnimationListener mOnAnimationListener; //播放停止监听private Bitmap mBitmap = null;private BitmapFactory.Options mBitmapOptions;//Bitmap管理类,可有效减少Bitmap的OOM问题public FramesSequenceAnimation(ImageView imageView, int[] frames) {mHandler = new Handler();mFrames = frames;mIndex = -1;mSoftReferenceImageView = new SoftReference<ImageView>(imageView);mShouldRun = false;mIsRunning = false;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) {return mFrames[mIndex];} else if (mIndex >= mFrames.length && isLoop) {return mFrames[mIndex = 0];} else if (isGoBack) {end();return mFrames[mIndex = 0];} else {end();return mIndex = -1;}}/*** How long this animation should last. The duration cannot be negative.* 与<code>setDelayMillis(long)</code>方法二选一** @param duration Duration in milliseconds* @throws java.lang.IllegalArgumentException if the duration is < 0* @attr ref android.R.styleable#Animation_duration* @see #setDelayMillis(long)*/public FramesSequenceAnimation setDuration(long duration) {if (mFrames.length == 0) {throw new IllegalArgumentException("Animation frame length == 0");}if (duration < 0) {throw new IllegalArgumentException("Animators cannot have negative duration: " +duration);}mDelayMillis = duration / mFrames.length;return this;}/*** 直接设置每帧间隔时间,与 <code>setDuration(long)</code> 方法二选一** @param delayMillis 每帧间隔时间,数值推荐:58,单位:毫秒* @throws java.lang.IllegalArgumentException if the duration is < 0* @attr ref android.R.styleable#Animation_duration* @see #setDuration(long)*/public FramesSequenceAnimation setDelayMillis(long delayMillis) {if (delayMillis < 0) {throw new IllegalArgumentException("Animators cannot have negative duration: " +delayMillis);}mDelayMillis = delayMillis;return this;}/*** 是否循环播放** @param isLoop*/public synchronized FramesSequenceAnimation setLoop(boolean isLoop) {this.isLoop = isLoop;return this;}/*** 是否返回第一帧** @param isGoBack*/public synchronized FramesSequenceAnimation setGoBack(boolean isGoBack) {this.isGoBack = isGoBack;return this;}/*** 播放动画,同步锁防止多线程读帧时,数据安全问题*/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;return;}mIsRunning = true;//新开任务到队尾去读下一帧mHandler.postDelayed(this, mDelayMillis);if (imageView.isShown()) {int imageRes = getNext();if (imageRes == -1) {return;}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);if (mOnAnimationListener != null) {mOnAnimationListener.onAnimationStart(FramesSequenceAnimation.this);}}/*** 暂停播放,下次start会继续播放*/public synchronized void stop() {if (!mShouldRun) {return;}mShouldRun = false;if (mOnAnimationListener != null) {mOnAnimationListener.onAnimationStopOrCancel(FramesSequenceAnimation.this);}}/*** 取消播放,下次start会从头播放*/public synchronized void cancel() {if (!mShouldRun) {return;}mShouldRun = false;mIndex = 0;if (mOnAnimationListener != null) {mOnAnimationListener.onAnimationStopOrCancel(FramesSequenceAnimation.this);}}/*** 播放结束*/private synchronized void end() {if (!mShouldRun) {return;}mShouldRun = false;if (mOnAnimationListener != null) {mOnAnimationListener.onAnimationEnd(FramesSequenceAnimation.this);}}/*** 直接返回第一帧*/public synchronized void goBackStart() {if (mFrames.length == 0) {throw new IllegalArgumentException("Animation frame length == 0");}mIndex = 0;ImageView imageView = mSoftReferenceImageView.get();imageView.setImageResource(mFrames[mIndex]);}/*** 设置停止播放监听** @param listener*/public FramesSequenceAnimation setOnAnimStopListener(OnAnimationListener listener) {this.mOnAnimationListener = listener;return this;}}/*** 停止播放监听*/public interface OnAnimationListener {void onAnimationStart(FramesSequenceAnimation animation);void onAnimationEnd(FramesSequenceAnimation animation);void onAnimationStopOrCancel(FramesSequenceAnimation animation);}
}

Android 解决帧动画卡顿问题相关推荐

  1. android帧动画卡顿现象,css3针对移动端卡顿问题的解决(动画性能优化)

    一.使用css,jquery,canvas制作动画 1.Canvas 优点:性能好,强大,支持多数浏览器(除了IE6.IE7.IE8),画出来的图形可以直接保存为 .png 或者 .jpg的图形: 缺 ...

  2. 【小知识点】解决Chrome动画”卡顿”的办法

    为动画DOM元素添加CSS3样式-webkit-transform:transition3d(0,0,0)或-webkit-transform:translateZ(0);这两个属性都会开启GPU硬件 ...

  3. lottie android 卡顿,说说动画卡顿的解决方案

    CSS3 动画卡顿解决方案 前端时间用animation实现H5页面中首页动画过渡,很简单的一个效果,首页加载一个客服头像,先放大,停留700ms后再缩小至顶部.代码如下 首页加载动画 .welcom ...

  4. css鼠标拖拉卡顿_浅谈CSS3 动画卡顿解决方案

    为什么会卡顿? 有一个前提必须要提,前端开发者们都知道,浏览器是单线程运行的.但是我们要明确以下几个概念:单线程,主线程和合成线程. 虽然说浏览器执行js是单线程执行(注意,是执行,并不是说浏览器只有 ...

  5. android 动画卡顿分析工具

    android 动画卡顿分析工具 Android应用性能优化之分析工具 上一次记录了解决过度绘制的过程,这一次,想先弄清个概念性的东西,就是如何判断顺不顺畅? 这东西其实最初我自己也觉得有点废话,用起 ...

  6. Android主线程耗时动画卡顿,Android性能优化实战之界面卡顿

    原标题:Android性能优化实战之界面卡顿 作者:红橙Darren https://www.jianshu.com/p/18bb507d6e62 今天是个奇怪的日子,有三位同学找我,都是关于界面卡顿 ...

  7. Android使用帧动画解决内存溢出问题

    Android使用帧动画解决内存溢出问题 参考文章: (1)Android使用帧动画解决内存溢出问题 (2)https://www.cnblogs.com/mcfawa/p/5192335.html ...

  8. 逍遥安卓模拟器卡android,逍遥安卓模拟器卡顿如何解决

    逍遥安卓模拟器是一款功能非常全面,性能十分稳定的安卓模拟器软件.可以模拟现今比较流行的一些手机型号,不仅能够方便测试不同手机的流畅性.还能够兼容各类软件及硬件,市面上百分之九十九的游戏它都可以完美运行 ...

  9. android最流畅手机,最流畅的5款安卓手机,系统满帧不卡顿,有没有你正在用的?...

    原标题:最流畅的5款安卓手机,系统满帧不卡顿,有没有你正在用的? 之前我们跟大家聊过哪些手机系统广告比较少,很多朋友说我遗漏了一加的氢os系统,今天我们来说说系统最流畅的5款安卓手机,欢迎大家一起讨论 ...

最新文章

  1. 对比电机和舵机中的PWM信号的作用
  2. python推荐书-python的书推荐
  3. 创业互联网公司如何搭建自己的技术框架
  4. NSAssert的使用
  5. rest_framework04:ModelSerializer/Serializer高级用法
  6. 信息学奥赛一本通 2059:【例3.11】买笔
  7. 实用常识 | 文件都在C盘,一点儿都不圆润,盘它!
  8. FabFilter Total Bundle 2021 for Mac(经典音频效果器合集)
  9. 自动化状态监测和工业4.0解决方案-Softing uaGate SI
  10. IDC机房网络系列视频
  11. 网站制作中关于版权声明的写法
  12. 如何理解普吕克坐标(几何理解)
  13. 俗话说:十赌九输。因为大多数赌局的背后都藏有阴谋。不过也不尽然,有些赌局背后藏有的是:“阳谋”。
  14. 【人工智能】— 贝叶斯网络、概率图模型、全局语义、因果链、朴素贝叶斯模型、枚举推理、变量消元
  15. 计算机软件工具有哪些,工具软件有哪些
  16. AUTOCAD(二)电脑桌绘制侧立面图
  17. [附源码]Python计算机毕业设计大学生体检管理系统
  18. 6 HomePlug AV MAC数据层
  19. 找回童年乐趣,在线玩超级玛丽、冒险岛、魂斗罗、坦克大战等经典游戏
  20. 将文件中的内容在控制台上输出

热门文章

  1. 2021-CVPR-图像修复论文导读《Image Inpainting Guided by Coherence Priors of Semantics and Textures》
  2. 【开心一刻】又想让马儿跑,又不给马儿吃草!
  3. C#链接SQL知识点
  4. Java - 什么是Session
  5. 重磅!《深度学习 500 问》已更新,(附完整下载)
  6. 2.命名空间实现机制
  7. python 保存网页图片到本地
  8. java调用clsid_java – Utgard – 拒绝访问
  9. Freeswitch 对接 unimrcpserver ASR调用
  10. python多元非线性回归_day-13 python库实现简单非线性回归应用