Android 的屏幕滚动操作不如 iPhone 流畅跟手,是什么原因导致的?

标签: android 屏幕 iphone | 发表时间:2014-07-22 09:30 | 作者:知乎用户(登录查看详情)
出处:http://www.zhihu.com
几个高票答案说的都是现象而非原因。
对 @劉長曦 专栏提到的 g+ 讨论做了个摘要,出处在此
https://plus.google.com/105051985738280261832/posts/2FXDCz8x93s

首先, 安卓不缺硬件加速的支持。从安卓 1.0 开始,安卓就支持硬件加速。菜单的显示/隐藏、提醒的滑动渐变、Activity 之间的过渡以及对话框的显示/隐藏等都是经过硬件加速的。

但硬件加速与安卓「窗口」的概念有关。比如以下这张截图,就包含四个窗口:


状态栏窗口 / 壁纸窗口 / 壁纸上的启动器窗口 / 菜单窗口

安卓一开始的设计目标是「提供开放的应用平台」,在这种设计思路下,安卓通过许多个独立的 UI 元素来分享屏幕:比如输入法窗口和应用窗口就是两个不同的窗口。而同一个安卓应用,也由许多 Activity 组成(比如联系人列表是一个 Activity,联系人详情是另一个 Activity),每个 Activity 又有自己的窗口。发现了吗? 安卓 UI 一切皆窗口:从主屏打开联系人应用,你看到的是主屏窗口和联系人列表窗口的动画;按下联系人查看详情,是联系人列表窗口和联系人详情窗口的动画;显示输入法,是键盘窗口的动画.. . 早期的安卓使用软件来渲染窗口内的内容:在 2.3 前,窗口内容由软件渲染,而窗口的组合 / 移动则通过硬件加速绘制。

自安卓 3.0 起支持「全」硬件加速,原先由 CPU 完成的窗口渲染可通过 GPU 完成了。但许多老应用的 UI 组件不支持此功能,所以在开发者菜单中打开强制硬件加速可能会有各种异常出现。

但为什么即便支持了硬件加速,也不能完全保证流畅度呢?事实上, 安卓的这个多窗口设计,意味着 GPU 需要同时支持不同进程的多个活动 GL 上下文。而即便到现在,多数移动 GPU 执行上下文切换的代价还是相当高的。

虽然安卓有堆硬件这一说,但 硬件加速的资源也很容易被安卓的渲染机制吃光。比方说,Tegra 2 足够在 60 帧下把 1280*800 屏幕的每个像素点渲染 2.5 次。但安卓 3.0 中,光是打开「所有应用」的视图,就需要绘制许多不同的窗口:需要对所有像素绘制一次背景;(往少了说)需要对一半的像素绘制一次 shortcut 和 widget 层;需要对一半的像素绘制一次图标和标签;也需要对所有像素绘制一次「所有应用」视图的黑色背景,还有「所有应用」视图的图标和标签...还不算对这些窗口做最后的组合,就把 GPU 的资源吃光了。当然,安卓对这个机制也有优化,比如把壁纸做成一个比屏幕大的窗口,这样在主屏滚屏时就不需要重绘,只要移动窗口就行。而这个绘制好了的窗口,就不需要额外的 GPU 计算量了。

另一方面,OpenGL 硬件加速绘图也不是万能的,Nexus S 和 Galaxy Nexus 中,每个 OpenGL 应用会占用 8MB 内存。要知道 2MB 的进程开支都是个不小的代价。这 8MB 内存可能从后台进程那里分配而来,造成应用切换速度的下降。

为了提升流畅度,还需要许多其他方面的努力:安卓 1.6 对前后台进程调度的优化、2.3 中对输入系统的重写、 加入并发的垃圾收集等。举一个流畅度不由硬件加速决定的例子:对滚屏操作,Nexus S 在 ICS 上的流畅度比在 2.3 中要低。这其实是因为计时机制发生了变化,有时在 ICS 中,当应用接收触摸事件并绘图时,可能在尚未准备好的情况下就获得了下一个事件,从而导致跟踪手指移动时可能错过一帧,但这时帧率仍然是 60fps (这个 bug 已经修复了)。

@Julius 提到的是关于浏览器的渲染情况。在这方面,安卓和 iOS 的主要差别并非来自硬件加速绘图。早期安卓在渲染网页时做了与 iOS 不同的折衷: 将网页以序列方式连续显示,而非贴片方式这样在滚屏和缩放时不会出现 Safari 那样的占位符,但渲染的帧率不够快。安卓 3.0 后改用了贴片方式,改善了滚屏和缩放的体验。但不论是安卓还是 iOS,贴片都是由 CPU 渲染的。

还有,「安卓后台应用太多吃资源」的说法也有问题。安卓的 UI 线程以默认优先级运行,后台线程以后台优先级运行。切换到后台的应用强制以后台优先级运行。而后台优先级利用了 Linux 的 cgroup 机制,它将所有的后台线程放进一个特别的调度组中, 它们满打满算也无法占用超过 10% 的 CPU 资源

「安卓的触摸事件不像 iOS 那样优先」的说法也是错的。你可以架梯子看看安卓进程的优先级设定
http://developer.android.com/reference/android/os/Process.html#THREAD_PRIORITY_AUDIO

总的来说,根据 Dianne 的说法,多窗口设计对屏幕绘制的开销,是影响安卓的流畅度的已知因素之一。但决定「流畅」的因素还有很多,抓住某个特定技术细节不放的说法都是有失偏颇的。

以上。

— 完 —
本文作者: 知乎用户(登录查看详情)

【知乎日报】 你都看到这啦,快来点我嘛 Σ(▼□▼メ)

此问题还有 41 个回答,查看全部。
延伸阅读:
android手机屏幕适配原理?
Android 手机没有 iPhone 好吗?

相关 [android 屏幕 iphone] 推荐:

Panasonic FX90 触控屏幕外,还支持 WiFi 传送至 Android 及 iPhone App

- Mr.aa - Engadget 中国版
对很多喜欢摄影的人来说,相机内置 WiFi 是一个很吸引人的功能,只是想到当中复杂的设定程序及有限制的功能,便令人泄气. Panasonic 看到这个缺点,便推出支持 Android 及 iPhone App 的 Lumix FX90,能够通过 WiFi 把相片传送到手机 App 上,然后传送到云端的 Lumix Club 或 Twitter、Facebook 或 YouTube 等等.

Android 的屏幕滚动操作不如 iPhone 流畅跟手,是什么原因导致的?

- - 知乎每日精选
几个高票答案说的都是现象而非原因. 对 @劉長曦 专栏提到的 g+ 讨论做了个摘要,出处在此. 首先, 安卓不缺硬件加速的支持. 从安卓 1.0 开始,安卓就支持硬件加速. 菜单的显示/隐藏、提醒的滑动渐变、Activity 之间的过渡以及对话框的显示/隐藏等都是经过硬件加速的. 但硬件加速与安卓「窗口」的概念有关.

android截取屏幕图片

- - BlogJava-首页技术区
                mButton.setText("截屏次数:"+mPrintNum);.         //1.构建Bitmap   .         //2.获取屏幕   .         //3.保存Bitmap    .             //文件   .                 Toast.makeText(this, "截屏文件已保存至SDCard/PrintScreenDemo/ScreenImage/下", Toast.LENGTH_LONG).show();   .

android 屏幕适配原则

- - CSDN博客推荐文章
      Android手机屏幕大小不一,有480x320,640x360,800x480.怎样才能让App自动适应不同的屏幕呢. 其实很简单,只需要在res目录下创建不同的layout文件夹,比如:layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.java里,而系统会根据屏幕的大小自己选择合适的layout进行使用.

下一代 iPhone 屏幕怎么走

- - 爱范儿 · Beats of Bits
大屏 iPhone 很有可能会在今年与大家见面了. 和 Android 不同,苹果一直对拥抱大屏幕表现得更加谨慎. 主要原因是苹果出于对 iOS 生态圈的保护,因为更多的分辨率代表应用开发者面临更高的开发成本,更难保证应用的质量. iPhone 4 的视网膜显示屏直接将初代 iPhone 分辨率提高了四倍,达到了 960 x 640.

Android 怎样击败 iPhone ?

- 菡萏 - 爱范儿 · Beats of Bits
关于标题这事,有很多头头是道的理论. 这个 Blog 也只是把那些中的一些拿出来再说一次而已. 因为,本文说的不是理论,而是已经发生的事实. 而且,和一般的认识不同, Android 在日本销量上击败 iPhone ,并非依靠廉价. Android 手机基本上保持了和 iPhone 同样的价位,甚至更贵.

iPhone为什么比Android好

- FlyFire - 果迷网
当一个人相信世间存在真相和真理并懂得真理永远无法对谎言妥协和宽容时,他的中立病就痊愈了. 我一向认为,对话这项事情是必须建立在双方有知识储备交集的情况下发生的,当然前提是独立思考得来的知识而不是谷歌或维基来的. 基于《人性论》或《道德情操论》也许可以就”要加薪弹钢琴“的道德问题进行一些交流,但是在这个事情的法律层次上交流可能就必须具备种花忍民《刑法》等知识.