帧动画遇到的OOM以及优化

####帧动画导致的OOM

参考文章:https://www.jianshu.com/p/edcca8d3dd00

Re-using Bitmaps (100 Days of Google Dev) https://www.youtube.com/watch?v=_ioFW3cyRV0

extending the concept of object pools to bitmaps.
object pools are a common technique for high-chrun
data types.

signal to the decoder to use an existing piece 
of memory to load that bitmap into.

reused bitmaps have a constraint with respect
to the physical size of the existing bitmaps.
SDK <= 18,the bitmap you're loading in and the bitmap
you're reusing must be the same exact size in order for
things to work properly.
SDK >= 19,existing bitmap can be >= incoming bitmap.

背景:最近项目里需要弄一个界面,基本没法用代码写,于是用帧动画,有33个图片.

开始没发现什么问题,直到有一次运行在三星s7上,OOM了我才意识到问题.

才想起来去看看AnimationDrawable相关的代码.

# AnimationDrawable.java
	
	private AnimationState mAnimationState;
	
    public void addFrame(@NonNull Drawable frame, int duration) {
        mAnimationState.addFrame(frame, duration);
        if (!mRunning) {
            setFrame(0, true, false);
        }
    }
private final static class AnimationState extends DrawableContainerState{
        public void addFrame(Drawable dr, int dur) {
            // Do not combine the following. The array index must be evaluated before
            // the array is accessed because super.addChild(dr) has a side effect on mDurations.
            int pos = super.addChild(dr);
            mDurations[pos] = dur;
        }
}	
DrawableContainerState.java

Drawable[] mDrawables;

        public final int addChild(Drawable dr) {
            final int pos = mNumChildren;
            if (pos >= mDrawables.length) {
                growArray(pos, pos+10);
            }

            dr.mutate();
            dr.setVisible(false, true);
            dr.setCallback(mOwner);

            mDrawables[pos] = dr;
            mNumChildren++;
            mChildrenChangingConfigurations |= dr.getChangingConfigurations();

            invalidateCache();

            mConstantPadding = null;
            mCheckedPadding = false;
            mCheckedConstantSize = false;
            mCheckedConstantState = false;

            return pos;
        }

通过查看代码可以发现,大致就是你创建DrawableAnimation然后再addFrame(Drawable dr,int dur). 一直不停的addFrame就会导致底层drawable数组不停线性变大. 这个过程是没法避免的,你要用帧动画的画就只能这样,导致在初始化的时候一下子干掉一大坨内存.

于是想办法优化.

  1. 刚开始想的DrawableAnimation是不是有一种方式,好比我三十个帧,每次只用5帧,然后本来30帧的动画我通过6次5帧的动画来实现. 这样就一直只有6个drawable.

  2. 后来上网搜发现有一个叫surfaceview的东西,允许你在非主线程更新界面. 大致意思就是通过Surfaceview来draw的drawable可以不在主线程中.一想本来主线程就有好多事情干,同样是draw各种drawable,如果能不在主线程就不在主线程吧.于是放弃第1个方案,折腾SurfaceView.

转载于:https://my.oschina.net/tanghaoo/blog/2222741

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值