修复FrameSequenceDrawable 播放bug

使用方式和解析链接:https://blog.csdn.net/humorousz/article/details/79552641

播放GIF偶尔出现频繁播、帧与帧之间的播放时长和实际的不同,原因是因为mLastSwap的使用

来看看mLastSwap的赋值代码:

 @Override
    public void draw(Canvas canvas) {
        synchronized (mLock) {
            checkDestroyedLocked();
            if (mState == STATE_WAITING_TO_SWAP) {
                // may have failed to schedule mark ready runnable,
                // so go ahead and swap if swapping is due
                if (mNextSwap - SystemClock.uptimeMillis() <= 0) {
                    mState = STATE_READY_TO_SWAP;
                }
            }

            if (isRunning() && mState == STATE_READY_TO_SWAP) {
                // Because draw has occurred, the view system is guaranteed to no longer hold a
                // reference to the old mFrontBitmap, so we now use it to produce the next frame
                Bitmap tmp = mBackBitmap;
                mBackBitmap = mFrontBitmap;
                mFrontBitmap = tmp;

                BitmapShader tmpShader = mBackBitmapShader;
                mBackBitmapShader = mFrontBitmapShader;
                mFrontBitmapShader = tmpShader;

                mLastSwap = SystemClock.uptimeMillis();

                boolean continueLooping = true;
                if (mNextFrameToDecode == mFrameSequence.getFrameCount() - 1) {
                    mCurrentLoop++;
                    if ((mLoopBehavior == LOOP_FINITE && mCurrentLoop == mLoopCount) ||
                            (mLoopBehavior == LOOP_DEFAULT && mCurrentLoop == mFrameSequence.getDefaultLoopCount())) {
                        continueLooping = false;
                    }
                }

                if (continueLooping) {
                    scheduleDecodeLocked();
                } else {
                    scheduleSelf(mFinishedCallbackRunnable, 0);
                }
            }
        }

这里的mLastSwap是获取SystemClock.uptimeMillis() 来实现,在赋值前还有其他代码在执行,那么就有可能每次播放获取回来的值都不一定相等,从而导致统计帧与帧之间的时长不准确

原代码:

 //计算是否满足交换普片的条件
        synchronized (mLock) {
            if (mDestroyed) {
                bitmapToRelease = mBackBitmap;
                mBackBitmap = null;
            } else if (mNextFrameToDecode >= 0 && mState == STATE_DECODING) {
                schedule = true;
                //计算下次调度的时间,上一张图片的展示时间加上上次调度的时间(mLastSwap就是上次调度的时间)
                mNextSwap = exceptionDuringDecode ? Long.MAX_VALUE : invalidateTimeMs + mLastSwap;
                mState = STATE_WAITING_TO_SWAP;
            }
        }

修改后代码:

//计算是否满足交换普片的条件
synchronized (mLock) {
    if (mDestroyed) {
        bitmapToRelease = mBackBitmap;
        mBackBitmap = null;
    } else if (mNextFrameToDecode >= 0 && mState == STATE_DECODING) {
        schedule = true;
//计算下次调度的时间,上一张图片的展示时间+上次调度的时间+代码执行时间(SystemClock.uptimeMillis()就是上次调度的时间加代码执行时间)
        mNextSwap = exceptionDuringDecode ? Long.MAX_VALUE : invalidateTimeMs + SystemClock.uptimeMillis();
        mState = STATE_WAITING_TO_SWAP;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值