荣耀彩票代理

  • 热门专题

Android6.0WMS(六)WMS动画管理

作者:  发布日期:2016-12-26 20:23:29
  • Android的应用启动时,或者切换Activity时都会以动画的方式显示前后两屏的切换过程。动画的原理很简单,把一帧一帧的图像按一定时间间隔显示出来就完成了。

    动画的绘制需要定时驱动,通常的做法是启动一个定时消息,每隔一定时间发一个消息,收到消息后输出一帧画面。Android支持VSync信号后,动画的驱动就有VSync信号承担了。

    荣耀彩票代理CHUANGKOUDONGHUADEJIBENYUANSUSHICHUANGKOUSurfaceZHONGBAOCUNDETUXIANG,TONGGUODUICHUANGKOUDESurfaceSHEZHIBUTONGDEBIANHUANJUZHENHETOUMINGDU,RANHOUQIANGZHISurfaceSHUAXIN,JIUNENGZAIPINGMUSHANGXIANSHICHUCHUANGKOUDEBIANHUAGUOCHENG。

    Choreographer对象初始化

    WOMENXIANLAIKANWMSZHONGDEmChoreographer BIANLIANG

        final Choreographer mChoreographer = Choreographer.getInstance();

    GAIBIANLIANGSHIYIGEXIANCHENGJUBUCUNCHUBIANLIANG,ZAITADEinitialValueZHONGCHUANGJIANLEChoreographerDUIXIANGBINGFANHUI。ZHEILISHIYONGXIANCHENGJUBUCUNCHUDEMULUJIUSHIBAOZHENGZAIXIANCHENGZHONGZHIYOUYIGEChoreographerDUIXIANG。

        public static Choreographer getInstance() {
            return sThreadInstance.get();
        }
        private static final ThreadLocal<Choreographer> sThreadInstance =
                new ThreadLocal<Choreographer>() {
            @Override
            protected Choreographer initialValue() {
                Looper looper = Looper.myLooper();
                if (looper == null) {
                    throw new IllegalStateException("The current thread must have a looper!");
                }
                return new Choreographer(looper);
            }
        };
    

    荣耀彩票代理ZAILAIKANXIAChoreographerDEGOUZAOHANSHU,ZHEILIZHUYAOSHICHUANGJIANLEFrameDisplayEventReceiverYONGLAIJIESHOUVSyncXINHAODEDUIXIANG。

        private Choreographer(Looper looper) {
            mLooper = looper;
            mHandler = new FrameHandler(looper);
            mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null;//接受VSync信号对象
            mLastFrameTimeNanos = Long.MIN_VALUE;
    
            mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());//计算刷新的时间间隔
    
            mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
            for (int i = 0; i <= CALLBACK_LAST; i++) {
                mCallbackQueues[i] = new CallbackQueue();
            }
        }

    FrameDisplayEventReceiver接受VSync信号

    WOMENZAIhttp://blog.csdn.net/kc58236582/article/details/52892384( Android6.0 VSyncXINHAORUHEDAOYONGHUJINCHENG )ZHEIPIANBOKEYIJINGFENXIGUOFrameDisplayEventReceiverDEYUANLILE,DANGVSyncXINHAOGUOLAISHI,ZUIHOUHUIDIAOYONGDAOFrameDisplayEventReceiverLEIDEonVsyncHANSHU:

            @Override
            public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
                if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
                    scheduleVsync();
                    return;
                }
    
    
                long now = System.nanoTime();
                if (timestampNanos > now) {
                    Log.w(TAG, "Frame time is " + ((timestampNanos  now) * 0.000001f)
                            + " ms in the future!  Check that graphics HAL is generating vsync "
                            + "timestamps using the correct timebase.");
                    timestampNanos = now;
                }
    
                if (mHavePendingVsync) {
                    Log.w(TAG, "Already have a pending vsync event.  There should only be "
                            + "one at a time.");
                } else {
                    mHavePendingVsync = true;
                }
    
                mTimestampNanos = timestampNanos;
                mFrame = frame;
                Message msg = Message.obtain(mHandler, this);
                msg.setAsynchronous(true);
                mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
            }

    ZHEIZHUYAOSHIFASONGLEYIGEXINHAO,ERSHISHIRunnableDENEIZHONGXIAOXI。

    YINCIWOMENZHUYAOKANXIAZHEIGELEIDErunHANSHU,ZHEILIJIUSHIDIAOYONGLEChoreographerDEdoFrameHANSHU。

            @Override
            public void run() {
                mHavePendingVsync = false;
                doFrame(mTimestampNanos, mFrame);
            }

    doFrame函数

    doFrameHANSHUZHUYAOYOUYIXIEVSyncSHIJIANLUOJICHULIRUGUOPAOQIGAIVSyncXINHAODEHUAHUIDIAOYONGscheduleVsyncLockedHANSHURANGSurfaceFlingerFASONGYIGEVSyncXINHAO,RUGUOZHENGCHANGHUIDIAOYONG4GEdoCallBacksHANSHU。

        void doFrame(long frameTimeNanos, int frame) {
            final long startNanos;
            synchronized (mLock) {
                ......
    
                long intendedFrameTimeNanos = frameTimeNanos;
                startNanos = System.nanoTime();
                final long jitterNanos = startNanos  frameTimeNanos;
                if (jitterNanos >= mFrameIntervalNanos) {
                    final long skippedFrames = jitterNanos / mFrameIntervalNanos;
                    final long lastFrameOffset = jitterNanos % mFrameIntervalNanos;
                    frameTimeNanos = startNanos  lastFrameOffset;
                }
    
                if (frameTimeNanos < mLastFrameTimeNanos) {
                    if (DEBUG_JANK) {
                        Log.d(TAG, "Frame time appears to be going backwards.  May be due to a "
                                + "previously skipped frame.  Waiting for next vsync.");
                    }
                    scheduleVsyncLocked();//让SurfaceFlinger立马发送一个VSync信号
                    return;
                }
    
                mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos);
                mFrameScheduled = false;
                mLastFrameTimeNanos = frameTimeNanos;
            }
    
            try {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#doFrame");
    
                mFrameInfo.markInputHandlingStart();
                doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);//按键相关
    
                mFrameInfo.markAnimationsStart();
                doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);//动画相关
    
                mFrameInfo.markPerformTraversalsStart();
                doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);//power相关
    
                doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
        }

    荣耀彩票代理doCallbacksHANSHU,WOMENSHOUXIANHUIJIANCHADANGQIANZHEIGECallBackTypeSHIFOUYOUDUIYINGDECallBackHUIDIAO,RUGUOMEIYOUZHIJIEreturn,RUGUOYOUDEHUAHUIDIAOYONGQIHUIDIAODErunHANSHU。

        void doCallbacks(int callbackType, long frameTimeNanos) {
            CallbackRecord callbacks;
            synchronized (mLock) {
                final long now = System.nanoTime();
                callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(
                        now / TimeUtils.NANOS_PER_MS);
                if (callbacks == null) {//没有对应CallBack回调
                    return;
                }
                mCallbacksRunning = true;
    
                // safe by ensuring the commit time is always at least one frame behind.
                if (callbackType == Choreographer.CALLBACK_COMMIT) {
                    final long jitterNanos = now  frameTimeNanos;
                    Trace.traceCounter(Trace.TRACE_TAG_VIEW, "jitterNanos", (int) jitterNanos);
                    if (jitterNanos >= 2 * mFrameIntervalNanos) {
                        final long lastFrameOffset = jitterNanos % mFrameIntervalNanos
                                + mFrameIntervalNanos;
                        if (DEBUG_JANK) {
                            mDebugPrintNextFrameTimeDelta = true;
                        }
                        frameTimeNanos = now  lastFrameOffset;
                        mLastFrameTimeNanos = frameTimeNanos;
                    }
                }
            }
            try {
                for (CallbackRecord c = callbacks; c != null; c = c.next) {
                    c.run(frameTimeNanos);//调用回调run函数
                }
            } 
            ......
        }

    ZHEIYEJIUYIWEIZHEDANGNIMEIYOUCallBackTypeDUIYINGDEHUIDIAO,MEICIVSyncXINHAOGUOLAIDAOdoFrameHANSHUZAIDAOdoCallBacksHANSHUDOUSHIMEIYOUYIYIDE。

    WMS启动动画

    NEIWOMENXIAMIANKANZAINALIBACallBackTypeDUIYINGDEHUIDIAOJIARULE,ZHEILIWOMENZHIGUANZHUDONGHUAXIANGGUANDE。

    SHANGMIANWOMENSHUODAOVSyncHUIBUDUANDEFASONG,MEIMIAO60DUOCI,DANSHIDONGHUABUHUIBUTINGDEBOFANG,JIUSHIZHEIGECallBackTypeDUIYINGDEHUIDIAOMEIYOU。NADONGHUADEQIDONGHEJIESHUYEJIUSHISHOUZHEIGEYINGXIANG,ERJIUSHIZAIWMSZHONGDIAOYONGscheduleAnimationLockedHANSHUFAQIDEDONGHUAQIDONG。

        void scheduleAnimationLocked() {
            if (!mAnimationScheduled) {
                mAnimationScheduled = true;
                mChoreographer.postFrameCallback(mAnimator.mAnimationFrameCallback);
            }
        }

    ZHEILIJIUSHIDIAOYONGChoreographerSHEZHICallBackType,XIANGGUANDEHUIDIAO。ZHEILIWOMENDEcallbackTypeSHICALLBACK_ANIMATION

        public void postFrameCallback(FrameCallback callback) {
            postFrameCallbackDelayed(callback, 0);
        }
    
        public void postFrameCallbackDelayed(FrameCallback callback, long delayMillis) {
            if (callback == null) {
                throw new IllegalArgumentException("callback must not be null");
            }
    
            postCallbackDelayedInternal(CALLBACK_ANIMATION,
                    callback, FRAME_CALLBACK_TOKEN, delayMillis);
        }

    WOMENZUIHOUKANpostCallbackDelayedInternalHANSHU,JIUSHIZAImCallBackQueuesDUIYINGDECallBackTypeZHONGZENGJIAXIANGYINGDEHUIDIAO。ZHEILIYEJIUSHIQIANMIANZAIWMSDEscheduleAnimationLockedDECANSHUmAnimator.mAnimationFrameCallbackJIUSHIHUIDIAO。

        private void postCallbackDelayedInternal(int callbackType,
                Object action, Object token, long delayMillis) {
            synchronized (mLock) {
                final long now = SystemClock.uptimeMillis();
                final long dueTime = now + delayMillis;
                mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
    
                if (dueTime <= now) {
                    scheduleFrameLocked(now);
                } else {
                    Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
                    msg.arg1 = callbackType;
                    msg.setAsynchronous(true);
                    mHandler.sendMessageAtTime(msg, dueTime);
                }
            }
        }

    荣耀彩票代理WOMENLAIKANXIAscheduleFrameLockedHANSHU,WOMENZHUYImFrameScheduledZHEIGEBIANLIANG,ZHEIGESHIHOUFUZHIWEItrue,HOUMIANJIUSHIYONGZHEIGEBIANLIANGLAIKONGZHIMEICIVSyncXINHAOGUOLAIDIAOYONGdoFrameHANSHUDESHIHOUSHIFOUYAOBOFANGDONGHUA

        private void scheduleFrameLocked(long now) {
            if (!mFrameScheduled) {
                mFrameScheduled = true;//注意这个变量
                if (USE_VSYNC) {
                    if (isRunningOnLooperThreadLocked()) {
                        scheduleVsyncLocked();//尽快让SurfaceFlinger中的EventThread发送一个VSync信号
                    } else {
                        Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
                        msg.setAsynchronous(true);
                        mHandler.sendMessageAtFrontOfQueue(msg);
                    }
                } else {
                    final long nextFrameTime = Math.max(
                            mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
                    if (DEBUG_FRAMES) {
                        Log.d(TAG, "Scheduling next frame in " + (nextFrameTime  now) + " ms.");
                    }
                    Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
                    msg.setAsynchronous(true);
                    mHandler.sendMessageAtTime(msg, nextFrameTime);
                }
            }
        }

    WOMENZAIHUIGUOTOULAIKANdoFrameHANSHU,DANGmFrameScheduledWEIfalseSHI,VSyncXINHAOGUOLAIGAIHANSHUZHIJIEreturnBUHUIBOFANGDONGHUA。

     

        void doFrame(long frameTimeNanos, int frame) {
            final long startNanos;
            synchronized (mLock) {
                if (!mFrameScheduled) {
                    return; // no work to do
                }
    

     

    JIXUKANpostCallbackDelayedInternalHANSHUZHONGZENGJIADEHUIDIAO,ZHEIGEHUIDIAOZAIWindowAnimatorDEGOUZAOHANSHUZHONGJIUXINJIANLEChoreographer.FrameCallbackHUIDIAO

        WindowAnimator(final WindowManagerService service) {
            mService = service;
            mContext = service.mContext;
            mPolicy = service.mPolicy;
    
            mAnimationFrameCallback = new Choreographer.FrameCallback() {
                public void doFrame(long frameTimeNs) {
                    synchronized (mService.mWindowMap) {
                        mService.mAnimationScheduled = false;
                        animateLocked(frameTimeNs);
                    }
                }
            };
        }

    WOMENZUIHOUKANHUIDIAODErunHANSHU,RUGUOSHIFRAME_CALLBACK_TOKEN,JIUSHIDIAOYONGHUIDIAODEdoFrameHANSHU。

        private static final class CallbackRecord {
            public CallbackRecord next;
            public long dueTime;
            public Object action; // Runnable or FrameCallback
            public Object token;
    
            public void run(long frameTimeNanos) {
                if (token == FRAME_CALLBACK_TOKEN) {
                    ((FrameCallback)action).doFrame(frameTimeNanos);
                } else {
                    ((Runnable)action).run();
                }
            }
        }


    播放动画

    荣耀彩票代理ZAISHANGMIANdoFrameHANSHUQIDONGDONGHUA,ERDONGHUADEBOFANGZHUYAOZAIWindowAnimatorDEanimateLockedHANSHU。

        private void animateLocked(long frameTimeNs) {
            ......
            boolean wasAnimating = mAnimating;
            mAnimating = false;//设置mAnimating为false
            mAppWindowAnimating = false;
    
            SurfaceControl.openTransaction();
            SurfaceControl.setAnimationTransaction();
            try {
                final int numDisplays = mDisplayContentsAnimators.size();
                for (int i = 0; i < numDisplays; i++) {
                    final int displayId = mDisplayContentsAnimators.keyAt(i);
                    updateAppWindowsLocked(displayId);
                    ......
    
                    // Update animations of all applications, including those
                    // associated with exiting/removed apps
                    updateWindowsLocked(displayId);
                    updateWallpaperLocked(displayId);
    
                    final WindowList windows = mService.getWindowListLocked(displayId);
                    final int N = windows.size();
                    for (int j = 0; j < N; j++) {
                        windows.get(j).mWinAnimator.prepareSurfaceLocked(true);//输出动画帧
                    }
                }
    
                for (int i = 0; i < numDisplays; i++) {
                    final int displayId = mDisplayContentsAnimators.keyAt(i);
    
                    testTokenMayBeDrawnLocked(displayId);
    
                    final ScreenRotationAnimation screenRotationAnimation =
                            mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation;
                    if (screenRotationAnimation != null) {
                        screenRotationAnimation.updateSurfacesInTransaction();
                    }
    
                    mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers();
    
                    if (mService.mAccessibilityController != null
                            && displayId == Display.DEFAULT_DISPLAY) {
                        mService.mAccessibilityController.drawMagnifiedRegionBorderIfNeededLocked();
                    }
                }
    
                if (mAnimating) {//为true,继续调用WMS的scheduleAnimationLocked播放下一帧
                    mService.scheduleAnimationLocked();
                }
    
                ......
            finally {
                SurfaceControl.closeTransaction();
            }
    
            ......
            boolean doRequest = false;
            if (mBulkUpdateParams != 0) {
                doRequest = mService.copyAnimToLayoutParamsLocked();
            }
    
            if (hasPendingLayoutChanges || doRequest) {
                mService.requestTraversalLocked();//重新刷新UI
            }
    
            if (!mAnimating && wasAnimating) {
                mService.requestTraversalLocked();
            }
        }

    animateLockedFANGFAXIANJIANGmAnimating SHEZHIWEIfalse,RANHOUDIAOYONGupdateWindowsLockedHANSHUHEupdateWallpaperLockedHANSHU,updateWindowsLockedZHEIGEHANSHUHUIDIAOYONGWindowStateAnimatorLEIDEstepAnimationLockerFANGFA,RUGUODONGHUAYIJINGXIANSHIWANZUIHOUYIZHEN,stepAnimationLockerFANGFAJIANGHUIWindowStateAnimatorLEIDEmAnimatingSHEZHIWEIfalse,BIAOSHIGAICHUANGKOUDEDONGHUAYIJINGJIESHU。ERZAIupdateWallpaperLockedHANSHUZHONGHUIPANDUANSUOYOUCHUANGKOUDEDONGHUASHIFOUYIJINGJIESHU,ZHIYAOYOUYIGEDONGHUAMEIJIESHU,JIUHUIJIANGwinAnimatorDEmAnimatingSHEZHIWEItrue。

            for (int i = windows.size()  1; i >= 0; i) {
                final WindowState win = windows.get(i);
                WindowStateAnimator winAnimator = win.mWinAnimator;
                if (winAnimator.mSurfaceControl == null) {
                    continue;
                }
    
                final int flags = win.mAttrs.flags;
    
                if (winAnimator.mAnimating) {
                    ......
                    mAnimating = true;
                }
            ......

    荣耀彩票代理ZAIHUIDAOanimatelockedFANGFA,DANGmAnimatingWEItrueSHIHUIDIAOYONGWMSDEscheduleAnimationLockedFANGFAJIXUXIANSHIDONGHUA,FOUZEDONGHUAXIANSHIJIUJIESHULE。

    XIAMIANWOMENZONGJIEXIADONGHUADEBOFANGGUOCHENG:XUYAOBOFANGDONGHUASHI,XIANHUIDIAOYONGWMSDEscheduleAnimationLockedFANGFA。DIAOYONGZHEIGEFANGFAHOU,CAIHUIJIESHOUBINGCHULIYICIVSyncXINHAO,DUIVSyncXINHAODECHULI,JIUSHISUOYOUXUYAOHUIZHIDECHUANGKOUGENJUGEZIDONGHUADESHEIZHIZHONGXINDIAOZHENGCHUANGKOUSurfaceDEBIANHUAJUZHENHETOUMINGDU;RUGUOHAIYOUCHUANGKOUDONGHUAXUYAOXIANSHI,JIXUDIAOYONGscheduleAnimationLockedFANGFAZHUNBEIXIAYIZHEN。

    ZHUNBEIYIZHENDONGHUADESHIJIANKEYIKUAYUEDUOGEVSyncXINHAOZHOUQI,DANSHIZHIYOUSHOUDAOVSyncXINHAOCAINENGGENGXINCHUANGKOUDESurfaceDESHUXINGHENEIRONG,DUIYINGYONGERYANSHOUDAOVSyncXINHAOYIWEIZHESurfaceFlingerZHONGYIJINGBASHANGCISHEZHIDEDONGHUASHUJUQUZOULE,KEYIANQUANDISHEZHIXIAYIZHENDONGHUADESHUXINGHENEIRONGLE。

    窗口动画对象WindowStateAnimator

    CHUANGKOUDUIXIANGWindowStateZHONGDINGYILEYIGELEIXINGWEIWindowStateAnimatorDECHENGYUANBIANLIANGmWinAnimator,YONGLAIBIAOSHICHUANGKOUDEDONGHUADUIXIANG。

    XIAMIANSHIYIXIECHENGYUANBIANLIANG

        boolean mAnimating;//表示是否正在显示动画
        boolean mLocalAnimating;//表示窗口动画是否已经初始化
        Animation mAnimation;//表示窗口动画对象
        boolean mAnimationIsEntrance;//
        boolean mHasTransformation;//表示当前动画的mTransformation是否可用
        boolean mHasLocalTransformation;//表示当前动画时一个窗口动画还是Activity动画
        final Transformation mTransformation = new Transformation();//变换矩阵对象

    DANGQIANZHENGZAIXIANSHIDEDONGHUAYOULIANGZHONGLEIXING,YIZHONGDECHUANGKOUQIEHUANDONGHUA,YIZHONGSHIActivityQIEHUANDONGHUA,ZHEILISHIYONGLEmLocalAnimatingHEmHasLocalTransformationFENBIEBIAOSHICHUANGKOUDONGHUADEZHUANGTAI。

    stepAnimationLockedSHIWindowStateAnimatorLEIZHONGXIANSHIDONGHUASHOUXIANDIAOYONGDEFANGFA,TAHUICHUSHIHUAWindowStateAnimatorDUIXIANGDEYIXIECHENGYUANBIANLIANG

        boolean stepAnimationLocked(long currentTime) {
            final DisplayContent displayContent = mWin.getDisplayContent();
            if (displayContent != null && mService.okToDisplay()) {
    
                if (mWin.isDrawnLw() && mAnimation != null) {//窗口准备好绘制了,窗口动画对象不为空
                    mHasTransformation = true;
                    mHasLocalTransformation = true;
                    if (!mLocalAnimating) {//还没有初始化窗口对象
                        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
                        if (mAnimateMove) {
                            mAnimateMove = false;
                            mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),//初始化窗口对象
                                    mAnimDw, mAnimDh);
                        } else {
                            mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
                                    displayInfo.appWidth, displayInfo.appHeight);
                        }
                        mAnimDw = displayInfo.appWidth;
                        mAnimDh = displayInfo.appHeight;
                        mAnimation.setStartTime(mAnimationStartTime != 1
                                ? mAnimationStartTime
                                : currentTime);
                        mLocalAnimating = true;// 设置为true代表已经初始化窗口对象
                        mAnimating = true;
                    }
                    if ((mAnimation != null) && mLocalAnimating) {
                        mLastAnimationTime = currentTime;
                        if (stepAnimation(currentTime)) {//通过时间判断动画是否显示完毕
                            return true;
                        }
                    }
                }
                mHasLocalTransformation = false;
                if ((!mLocalAnimating || mAnimationIsEntrance) && mAppAnimator != null//没有设置窗口动画或者窗口动画结束了
                        && mAppAnimator.animation != null) {
                    // 如果有Activity动画,将mAnimating设为true
                    mAnimating = true;
                    mHasTransformation = true;
                    mTransformation.clear();
                    return false;
                } else if (mHasTransformation) {
                    // Little trick to get through the path below to act like
                    // we have finished an animation.
                    mAnimating = true;
                } else if (isAnimating()) {
                    mAnimating = true;
                }
            } else if (mAnimation != null) {
                mAnimating = true;
            }
    
            if (!mAnimating && !mLocalAnimating) {
                return false;
            }
    
    
            mAnimating = false;
            mKeyguardGoingAwayAnimation = false;
            mAnimatingMove = false;
            mLocalAnimating = false;
            ......
            mHasLocalTransformation = false;
            ......
            mTransformation.clear();
            ......
    
            return false;
        }

    GAIFANGFADEGONGZUOJIUSHISHEZHIWindowStateAnimatorDUIXIANGDEJIGECHENGYUANBIANLIANG,SHOUXIANDIAOYONGWindowStateDUIXIANGDEisDrawnLwLAIPANDUANCHUANGKOUXITONGDEZHUANGTAI,ZHIYOUZHUNBEIHAOLECAINENGXIANSHI,JIEZHEPANDUANmAnimationSHIFOUWEIKONG,BUWEIKONGDAIBIAOYIJINGSHEZHIHAOLEDONGHUADUIXIANG。

    荣耀彩票代理JIEXIALAIPANDUANmLocalAnimatingBIANLIANGDEZHI,WEIfalseZEDIAOYONGmAnimationDEintializeFANGFALAIWANCHENGDONGHUADUIXIANGDECHUSHIHUA(ZHUYAOSHEZHIDONGHUADEGAODUHEKUANDU),RANHOUJIANGmLocalAnimatingHEmAnimatingSHEWEItrue。WANCHENGCHUSHIHUAHOU,JIEZHEDIAOYONGstepAnimationFANGFALAIPANDUANDONGHUASHIFOUYIJINGXIANSHIWANCHENG,MEIYOUWANCHENGFANHUItrue。

    RUGUOMEIYOUSHEZHIDONGHUAHUOZHEDONGHUAYIJINGJIESHULE,ZEHAIYOUPANDUANCHUANGKOUSUOZAIDEActivitySHIFOUHAICUNZAIDONGHUA,RUGUOYOU,JIANGmAnimatingSHEZHItrue(BIAOSHIHAIYAOJIXUBOFANGDONGHUA),RUGUOTONGSHImHasTransformationDEZHIRENGRANWEItrue,HUOZHEisAnimatingFANGFAFANHUItrue,YEJIANGmAnimatingSHEZHIWEItrue。

    荣耀彩票代理isAnimatingHUIGENJUDANGQIANDONGHUADUIXIANGmAnimationSHIFOUWEIKONG,TADEFUJIACHUANGKOUDEDONGHUADUIXIANGSHIFOUWEIKONG,YIJICHUANGKOUSUOZAIDEActivityDEDONGHUADUIXIANGSHIFOUWEIKONGDENGTIAOJIANLAIPANDUAN,ZHEIBIAOSHIZHIYAOYOUKENENGmAnimatingJIUHUISHEZHIWEItrue。ZHEIYANGDEMUDEJINLIANGRANGDONGHUAWANCHENGXIANSHI,JISHIMEIYOUKEXIANSHIDEDONGHUA,DUOSHUAXINJICIBUHUIYOUFUZUOYONG,DANRUGUOSHAOHUALEYICI,PINGMUSHANGJIUKENENGLIUXIABUZHENGQUEHUAMIANLE。

        boolean isAnimating() {
            return mAnimation != null
                    || (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
                    || (mAppAnimator != null && mAppAnimator.isAnimating());
        }


    我们再看看动画的生成过程,WindowStateAnimator的prepareSurfaceLocked方法来完成计算一帧动画并显示工作:
     

        public void prepareSurfaceLocked(final boolean recoveringMemory) {
            ......
            computeShownFrameLocked();//计算要显示的动画帧
    
            setSurfaceBoundariesLocked(recoveringMemory);
    
            if (mIsWallpaper && !mWin.mWallpaperVisible) {
                hide();//如果是壁纸窗口,隐藏
            } else if (w.mAttachedHidden || !w.isOnScreen()) {
                hide();//如果窗口不可见,隐藏
                ......
            } else if (mLastLayer != mAnimLayer
                    || mLastAlpha != mShownAlpha
                    || mLastDsDx != mDsDx
                    || mLastDtDx != mDtDx
                    || mLastDsDy != mDsDy
                    || mLastDtDy != mDtDy
                    || w.mLastHScale != w.mHScale
                    || w.mLastVScale != w.mVScale
                    || mLastHidden) {//每个值是否有变化
                displayed = true;
                mLastAlpha = mShownAlpha;
                mLastLayer = mAnimLayer;
                mLastDsDx = mDsDx;
                mLastDtDx = mDtDx;
                mLastDsDy = mDsDy;
                mLastDtDy = mDtDy;
                w.mLastHScale = w.mHScale;
                w.mLastVScale = w.mVScale;
    
                if (mSurfaceControl != null) {
                    try {
                        mSurfaceAlpha = mShownAlpha;
                        mSurfaceControl.setAlpha(mShownAlpha);
                        mSurfaceLayer = mAnimLayer;
                        mSurfaceControl.setLayer(mAnimLayer);
                        mSurfaceControl.setMatrix(
                                mDsDx * w.mHScale, mDtDx * w.mVScale,
                                mDsDy * w.mHScale, mDtDy * w.mVScale);
    
                        if (mLastHidden && mDrawState == HAS_DRAWN) {
                            if (showSurfaceRobustlyLocked()) {//输出动画帧
                                mLastHidden = false;
                                if (mIsWallpaper) {
                                    mService.dispatchWallpaperVisibility(w, true);
                                }
                                mAnimator.setPendingLayoutChanges(w.getDisplayId(),
                                        WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
                            } else {
                                w.mOrientationChanging = false;
                            }
                        }
                        if (mSurfaceControl != null) {
                            w.mToken.hasVisible = true;
                        }
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Error updating surface in " + w, e);
                        if (!recoveringMemory) {
                            mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
                        }
                    }
                }
            }
            ......
        }

    荣耀彩票代理GAIHANSHUXIANDIAOYONGLEcomputeShownFrameLockedHANSHUJISUANDANGQIANXUYAOXIANSHIDEDONGHUAZHENSHUJU,mAnimLayerBIAOSHICHUANGKOUDEZZHOU、mShownAlphaCHUANGKOUTOUMINGDU;mDsDx、mDtDx、mDsDyHEmDtDyBIAOSHIERWEIBIANHUANJUZHEN;w.mHScale w.mVScaleBIAOSHICHUANGKOUDESUOFANGBILI

    ZHIYOUJISUANCHUDESHUJUHESHANGYICISHUJUBUYIYANGCAIHUIDIAOYONGshowSurfaceRobustlyLockedSHUCHUDONGHUAZHEN。

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规