如何理解Android属性动画

和之前的文章一样,没有使用代码进行讲解,所以读者阅读起来可能有点吃力。我建议阅读的时候,结合源码,效果更佳。文章必定会有疏漏的地方,读者在阅读过程如发现,请务必指正,不甚感激!

动画是什么?

这或许是个简单的问题,很多人都会回答说“动画就是一帧帧静态画面的连续播放”。这样的回答表明,动画的组成元素是每一帧画面。我们看到的2D动画就是这样。然而我们发现在电影院,2D动画几乎已经绝迹,普遍都是画质更为逼真,人物表情更为丰富的CG动画。制作CG动画有一个重要的步骤就是--建模,比如人物,花草,建筑物等等都是被独立看待的一个个模型。我们以CG动画的角度看,动画的组成元素是一个个独立的模型。每个模型都有本身的属性,比如头发的弧度,手臂的位置,瞳孔的颜色等等。当我们把动画以帧的方式进行分割,实际上就割裂了属性变化的连续性。而CG动画则是以事物属性为关注点,并且注重属性变化的连续性,所以效果就更加逼真灵动。

从2D动画到CG动画,是技术的进步,也是认知的提升。Android动画框架也经历了这样的转变。

Android早期提供的动画框架被称为帧动画,就像2D动画一样,所以也有着2D动画的缺点--动画效果卡顿。这使得Android在3.0推出了全新的动画框架--属性动画。属性动画与CG动画的核心理念是一样的--所动画的是属性,而不是帧。Androd官方把属性动画框架的开发称之为--黄油计划,原因显而易见,就是让动画像黄油一样顺滑。

我在此谈的就是属性动画。

动画回调何时执行?

在回答这个问题之前先谈谈主线程。主线程又称UI线程,主要作用是处理交互事件,执行界面绘制等功能。每个人都能拿这个回答去搪塞别人,回答问题的人未必在头脑中建立了主线程运转机制的模型。线程交互的基本模型就是生产者-消费者模型。在这个模型中工作线程将生产的Runnable,不断发送到主线程供其消费。主线程的Run方法存在一个死循环,在这个死循环中,它不断处理别人生成的Runnable.。投递给主线程的Runnable一般分为两类。一类是系统产生的事件,如交互事件,四大组件的生命周期回调;另一类事件是程序自身产生的--那些post系列方法发送的Runnable,动画事件回调,界面绘制事件。四大组件的生命周期回调我们不谈及,他是由系统操控的。这些Runnable就是胡乱的塞到主线程的消息队列中的吗?显然不是,绝对不是!

问题来了,这些Runnable如何在主线程中进行组织?

所谓组织就是给这些Runnable排个序,排序标准有两个:一是这些Runnale之间固有的先后顺序,比如交互事件的处理就应该在绘制事件前面,因为我们只有计算了手移动了多少距离,才能决定屏幕中的控件移动多少距离;二是以时间排序,比如postDelayed方法就会延迟Runnable的执行。这些事件在主线程的处理顺序是:交互事件回调--动画事件回调--界面绘制。Android系统每隔16ms发出VSYNC信号,接收到VSYNC信号,主线程会依次执行交互事件回调,动画事件回调,最后触发UI绘制。在Android中实现Runnable调度组织功能的是Choreographer,它为以上三类事件的分别维护了一个列表。

属性动画如何将动画回调事件交给Choreographer?

我能想到最简陋的动画效果实现就是,一个放映员不断切换幻灯片,只要放映员切换速度足够快,也能达到"动画"的效果。这里有个重要的角色就是切换幻灯片的放映员。Android的属性动画也需要这样一个放映员,我们称这个放映员为动画引擎。

Android属性动画的引擎只有一个,所有的动画都由这个引擎调度。这样做的好处是所有动画分享相同的时间,那么动画之间就能同步。在Android中动画引擎的实现类是AnimationHandler--组织编排所有动画的执行(每个动画的启动时间不一样,另外有的动画会延迟执行),根据动画时间计算动画值。AnimationHandler会拿到Choreographer的一个实例,并将自己放置到Choreographer所维护的动画事件列表中,随着每一次VSYNC信号的到来,而得到执行。

为什么属性动画会顺滑?

之前提到了Android系统会每隔16ms发出VSYNC信号。为什么是16ms?因为人类视觉能接受到画面变化的时间就是16ms,当大于16ms,人就会感觉到画面不连续,我们称为卡顿,所以Android会每隔16ms刷新一次画面。一般的,我们在动画回调中修改了View的某些属性,然后紧接着在View的绘制中应用了了这些属性,这一切都是在这16ms内完成的,因而我们感觉到动画效果是顺滑。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,392评论 25 707
  • 1. 前言 上一篇文章《Android Animation运行原理详解》介绍了插间动画的原理,而Android3....
    SparkInLee阅读 13,527评论 5 52
  • 为了理解App是如何进行渲染的,我们必须了解手机硬件是如何工作,那么就必须理解什么是VSYNC。 在讲解VSYNC...
    Viking_Den阅读 4,657评论 1 8
  • 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? 知道Android...
    CoorChice阅读 26,381评论 42 312
  • 年龄越来越大,经历越来越多,人变得成熟了,但能够放心说出来的话,可以聊得来的人也越来越少。认识的人有很多,通讯录里...
    蓦荻阅读 296评论 0 0