帧动画加载大量图片OOM的解决办法
2016-06-24 14:08
309 查看
这是在别人代码基础上更改的。
代码如下:
代码如下:
public class SceneAnimation { /** * target imageView */ private ImageView mImageView; /** * frame resources */ private int[] mFrameRes = null; /** * different duration in frame */ private int[] mDurations = null; /** * specific duration */ private long mDuration; private int mCurrentFrame; private boolean mStop; private boolean mRepeat; private boolean mSpecificDuration; private Runnable mAction = null; private OnFramePlayListener mListener; public interface OnFramePlayListener{ void onFrame(int frame); void onEnd(); } public SceneAnimation(ImageView pImageView, int[] pFrameRes, int pDuration) { initialize(pImageView, pFrameRes); mDuration = pDuration; mSpecificDuration = true; } public SceneAnimation(ImageView pImageView, int[] pFrameRes, int[] pDurations) { initialize(pImageView, pFrameRes); mDurations = pDurations; mSpecificDuration = false; } private void initialize(ImageView pImageView, int[] pFrameRes) { mImageView = pImageView; mFrameRes = pFrameRes; mCurrentFrame = 0; mStop = false; mRepeat = false; } /** * @return the total time of animation */ public long getTotalTime(){ if(mFrameRes != null) { if (mSpecificDuration) { return mDuration * (mFrameRes.length - 1); } else if(mDurations != null){ long totalTime = 0; for (int i = 0; i < mDurations.length; i++) { totalTime += mDurations[i]; } return totalTime; }else{ return 0; } } return 0; } public void setRepeat(boolean mRepeat) { this.mRepeat = mRepeat; } public void setOnFramePlayListener(OnFramePlayListener mListener) { this.mListener = mListener; } @SuppressWarnings("deprecation") private void setBackground(View view, Drawable drawable) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { view.setBackgroundDrawable(drawable); } else { view.setBackground(drawable); } } private void doPlay(){ if(null == mImageView) return; mImageView.postDelayed(mAction = new Runnable() { public void run() { if(mCurrentFrame < mFrameRes.length && !mStop) { setBackground(mImageView, ContextCompat.getDrawable(mImageView.getContext(), mFrameRes[mCurrentFrame])); if(mListener != null){ mListener.onFrame(mCurrentFrame); if(mCurrentFrame == mFrameRes.length - 1){ mListener.onEnd(); } } mCurrentFrame++; doPlay(); }else if(mRepeat && !mStop){ startPlay(); } } }, getDelayTime()); } /** * 由于都是大图片所以动画播放过程中会频繁gc * 所以动画时间间隔需要缩短,暂时没想到更好的办法,只是 * 把时间间隔缩短为原来的65%比较接近我们期望的动画时长 * @return */ private long getDelayTime() { if(mSpecificDuration) return (long)(mDuration * 0.65d); else{ if(mCurrentFrame - 1 < mDurations.length){ return (long)(mDurations[mCurrentFrame - 1] * 0.65d); }else{ return 0; } } } public void startPlay(){ if(mFrameRes != null) { mCurrentFrame = 0; setBackground(mImageView, ContextCompat.getDrawable(mImageView.getContext(), mFrameRes[mCurrentFrame])); mCurrentFrame++; doPlay(); } } /** * 停止动画,释放资源 */ public void stopImmediately() { if(mImageView != null){ mStop = true; if(mAction != null) { mImageView.removeCallbacks(mAction); mAction = null; } } } }
相关文章推荐
- ant编译OpenACS和myeclipse下使用ant编译OpenACS
- HBase 1.2.1 的集群搭建
- 同一个进程内open两次同一文件并读写
- 深入JDK源码之Arrays类中的排序查找算法(转)
- python操作mongodb之六自定义类型存储
- linux下mysql的卸载、安装全过程及遇到"MySQL提示:The server quit without updating PID file问题的解决办法"
- Android 之 打包混淆ProGuard
- ssm框架搭建+easyui增删改查实现
- git删除远程remote分支
- mysql sql规范整
- MQTT 客户端应用及常见问题(C#)
- git删除远程remote分支
- 【风马一族_Java】java的一种IDE
- Android 内存泄漏总结
- 文章标题
- 叛逆才能保持清醒
- 20行代码完成WebService请求
- iOS开发NSDictionary字典介绍
- 小米推送简单使用方法
- 关于Xposed