android窗口动画体系,Android 7.1 GUI系统-窗口管理WMS-动画的执行(七)

 2023-09-16 阅读 13 评论 0

摘要:前面只是动画资源的加载过程,下面看下动画是怎么执行起来的?前面在分析窗口申请的过程中,分析过relayoutWindow中的调用performSurfacePlacement,在这个函数的最后调用了mService.scheduleAnimationLocked(),来安排动画的执行。void sched

前面只是动画资源的加载过程,下面看下动画是怎么执行起来的?

前面在分析窗口申请的过程中,分析过relayoutWindow中的调用performSurfacePlacement,在这个函数的最后调用了mService.scheduleAnimationLocked(),来安排动画的执行。

void scheduleAnimationLocked() @WindowManagerService.java{

if (!mAnimationScheduled) {

mAnimationScheduled = true;

android动画有哪几类。//通过Choreographer设置一个触发源,mChoreographer 是通过ThreadLocal保存的,所以它是一个线程中的单实例。

mChoreographer.postFrameCallback(mAnimator.mAnimationFrameCallback);

}

}

mAnimationScheduled为true,表示当前正在scheduleanimantion,在mAnimationFrameCallback的回调中会把mAnimationScheduled再次置为false。

Choreographer设置的动画的触发源是什么?这样看下Choreographer这个类的主要功能是什么:Choreographer会接从显示系统接收定时脉冲(如Vsync),然后安排渲染下一个显示帧的工作。动画的触发源就是Vsync。

android 属性动画?在动画框架或view层次中,应用程序通常使用较高的抽象跟Choreography间接交互,如:使用android.animation.ValueAnimator#start方法,post一个动画与渲染帧同步处理。

使用View#postOnAnimation方法,post一个Runnable,让其在下一个显示帧开始时调用。

有些情况,可能需要直接使用choreography的函数,如:

如果应用程序想在不同的线程里做渲染,可能是用GL,或者不使用animation框架、View层级,又要确保跟显示同步,这时可以使用Choreographer#postFrameCallback。

Choreography一方面接收VSYNC信号,另一方面把这一事件转发给感兴趣的人,所有希望监听VSYNC信号的对象都要在Choreography中注册。

scheduleAnimationLocked中调用的是postFrameCallback,然后直接调用了postFrameCallbackDelayed。

android动画不停、public void postFrameCallbackDelayed(FrameCallback callback, long delayMillis) @Choreographer.java{

postCallbackDelayedInternal(CALLBACK_ANIMATION,

callback, FRAME_CALLBACK_TOKEN, delayMillis);

}

这里的CALLBACK_ANIMATION是回调类型,Choreography将注册者分为三个类型:CALLBACK_INPUT,CALLBACK_ANIMATION,CALLBACK_TRAVERSAL(处理layout和draw)。

注册的回调都放在一个数组mCallbackQueues中。

android两种动画,当Vsync信号产生后,Choreography会通过doCallbacks,进一步调用到相应注册对象的doFrame函数。

这里回调的是WindowAnimator.java中的doFrame。

WindowAnimator.java

mAnimationFrameCallback = new Choreographer.FrameCallback() {

public void doFrame(long frameTimeNs) {

synchronized (mService.mWindowMap) {

android 动画框架,mService.mAnimationScheduled = false;

animateLocked(frameTimeNs);

}

}

};

通过animateLocked,各种动画开始单步执行。

android性能 动画加载。private void animateLocked(long frameTimeNs) {

//当前时间。

mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;

//记录上一次的动画状态,判断动画是否结束。

boolean wasAnimating = mAnimating;

//先本地记录对surface的更改,最后统一统计给surfaceflinger。

Android加载动画?SurfaceControl.openTransaction();

SurfaceControl.setAnimationTransaction();

try {

final int numDisplays = mDisplayContentsAnimators.size();

//循环处理每个显示屏中的动画。

for (int i = 0; i < numDisplays; i++) {

android动画优化?final int displayId = mDisplayContentsAnimators.keyAt(i);

//执行appTransition中设置的appWindow动画,

updateAppWindowsLocked(displayId);

//执行屏幕旋转动画,比如屏幕的横竖屏。

final ScreenRotationAnimation screenRotationAnimation

=displayAnimator.mScreenRotationAnimation;

android欢迎动画、if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {

if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) {

//动画没有结束,通过setAnimating把mAnimating设置为true。

setAnimating(true);

}else{

//动画结束了。

android开源动画。…...

}

}

//更新每个所有应用中的动画,包括与退出、移除app相关的。这里会执行WindowStateAnimator动画。

updateWindowsLocked(displayId);

updateWallpaperLocked(displayId);

android三种动画。final WindowList windows = mService.getWindowListLocked(displayId);

final int N = windows.size();

for (int j = 0; j < N; j++) {

//更新surface。

windows.get(j).mWinAnimator.prepareSurfaceLocked(true);

}

安卓 动画?}

//动画还没结束,再次调用 scheduleAnimationLocked。

if (mAnimating) {

mService.scheduleAnimationLocked();

}

}finally{

安卓页面切换动画,//统一提交给surfaceflinger处理。

SurfaceControl.closeTransaction();

}

//在执行动画最后一步step时, mAnimating为false, wasAnimating记录是上一次mAnimating 的值,所以为true,这里将请求一次遍历,计算窗口大小,performsurface等。

if (!mAnimating && wasAnimating) {

mWindowPlacerLocked.requestTraversal();

android动画,}

}

不管那类动画,要更新动画调用的都是stepAnimationLocked,指定动画的单步,就是每个特定的时间计算动画的最新状态。如果函数true,说明动画还在进行,否则返回false。

boolean stepAnimationLocked(long currentTime) @WindowStateAnimator.java{

//mWasAnimating 保存上一次的状态,通过比较mWasAnimating 和 isAnimationSet(),就知道动画是刚刚开始,还是停止了。mWasAnimating = mAnimating;

//第一次执行动画,需要做些初始化。

android有哪几种动画。if (!mLocalAnimating) {

mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),

displayInfo.appWidth, displayInfo.appHeight);

mAnimDx = displayInfo.appWidth;

mAnimDy = displayInfo.appHeight;

mAnimation.setStartTime(mAnimationStartTime != -1

? mAnimationStartTime : currentTime);

//已经执行过一次, mLocalAnimating置为true。

mLocalAnimating = true;

//表示当前正在执行动画。

mAnimating = true;

}

// mAnimation做非null判断,因为不是每个WindowStateAnimator当前都有动画在执行。

if ((mAnimation != null) && mLocalAnimating) {

mLastAnimationTime = currentTime;

//执行一次单步,计算当前的动画状态,返回true,表示动画还没结束。

if (stepAnimation(currentTime)) {

return true;

}

}

}

如何执行一个单步。

private boolean stepAnimation(long currentTime) @WindowStateAnimator.java{

currentTime = getAnimationFrameTime(mAnimation, currentTime);

mTransformation.clear();

final boolean more = mAnimation.getTransformation(currentTime, mTransformation);

return more;

}

上面的函数会根据mAnimation设置的开始时间,结合当前时间,计算出动画的新的变换值,动画的四个要素是平移、缩放、旋转、透明度,在getTransformation()中将会根据设置的属性分别调用相应类型的applyTransformation,计算变换值,保存在mTransformation中

中,其中平移、缩放、旋转由mMatrix表示,透明度由mAlpha表示。

完成动画数据的计算,接着就是真正显示到屏幕上,先由WMS对surface做更新,具体就是prepareSurfaceLocked的调用。

最后通过SurfaceControl.closeTransaction()关闭业务,将surface中的更新信息统一传给SurfaceFlinger,然后写入到framebuffer中,完成显示。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/67569.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息