积分3261
UID53387
M币 个
M金 ¥
回帖0
主题
经验 点
祝福 消耗值
金币 个
阅读权限60
精华
注册时间2011-4-3
最后登录1970-1-1
|
转自魅族的fzylovell, 如违反请通知
刚看到有煤油抱怨M9自带的Launcher的滑动效果不是很流畅,下面我结合我自己的一些经验给大家分析下。
我是一个刚入行的android程序员(做了半年),我也曾做过滑动桌面类似的组件,当然没有Launcher那么复杂,只是有几屏的图标可以滑来滑去,并且可以点击,添加和删除就可以了。我当时在做了View缓存优化之后测试性能的时候发现帧数其实还不错(Nexus One2.3测试),静止的时候有57fps左右(让其不断的重画),滑动的时候也有46~54fps左右(UI组件刷新率一般手机好像都限制为60fps以下),但是总感觉不是很流畅,我思考和尝试了2天,最后我确信这个卡卡的感觉就在放手的那一刹那。
正常情况下人的眼睛看界面效果不是需要你滑动的有多快就觉得用户体验是最好的,而是要有一个平滑的过渡效果,人的视觉感受才更舒服,太快的话反而觉得很突兀,不自然。以现在主流单核1GHZ机器的水准,50fps的帧数只要优化稍微好点完全没问题,而滑动效果这个最关键的地方就是手放开之后的自由滑动状态的的速度和动画时间的控制,卡卡的是因为切换时速度突然变化,所以感觉卡。因为由于android API的某些机制的原因,想要做得到这一点并不容易。还有煤油反应说滑动有延迟,就是手指滑动一段距离之后画面才跟着动,其实我觉得这个最好解决了,下面我一一解释。
我想大多数android定制厂商自己写自带app第一肯定是参考官方实现,然后做出相应修改和优化。如果你是白手起家凭空写出一个Launcher我只能说你太NB了。我当时也是参考了官方Launcher和ADWLauncher的源码,取出了其中一部分自己需要的功能,然后一点点看懂意思,再尝试优化。但是说实话官方自带的Launcher的滑动效果也不好。
主要优化应该都在WorkSpace这个类中。
从触摸事件传递的顺序来看,应该是 public boolean onInterceptTouchEvent(MotionEvent ev)------>当发生ACTION_MOVE事件后,一般会调用public boolean onTouchEvent(MotionEvent ev)方法,一般我们会在onTouchEvent受到ACTION_MOVE之后才真正决定开始移动桌面,但是正是这个调用onTouchEvent方法的时机决定了滑动的延迟,因为手指在点击屏幕的时候会不断产生touch事件(屏幕刷新率60HZ),虽然你自己认为可能手指没有移动,其实屏幕扑捉的坐标很精细,坐标是在不停移动的,所有我们一般会有一个降噪的过程,就是在移动多少像素范围内认为你是点击而不是移动,设个值设置太小会照成总以为你是在移动造成总“点不了”,太大的话又会造成滑动延迟,因为我们认为只有你超出这个范围之后我们才会调用onTouchEvent去真正滑动屏幕。官方的值好像是24px还是16px(ViewConfiguration的TOUCH_SLOP),好像每个版本都不一样,可以尝试下设置到更小,但是我认为最小不能低于8px,否则真的"很难点"。
当手指在屏幕上移动的时候,这时屏幕和手指移动的距离应该是一样的,当放开的时候会收到 ACTION_UP的事件,这时候会调用 snapToScreen(whichScreen)决定自由滑动到哪个屏幕.在此方法中就是控制整个滑动效果的重点所在。这里主要体现在,自由滑动的时间和速度。而时间跟手指离开屏幕时的滑动速度和将要滑动的距离有关。一般我认为最小的duration不要低于400ms到500ms,最高的话不要超过1s。
具体的参数最后会传入这个方法:public void startScroll(int startX, int startY, int dx, int dy, int duration) 这是来自Scroller类的一个方法,他控制了整个滑动效果。当初在构造Scroller这个对象的时候,如果是默认的构造方法,会使用默认的Interpolator,但是这个默认的Interpolator我感觉对滑动效果的控制并不好,并造成了进入自由滑动后速度突然切换的情况。ADWLauncher就是对这个Interpolator进行了自定义感觉比官方的要好点,这个最最重要最难控制的我感觉就是对自定义Interpolator的实现。其实Interpolator就是一个控制滑动效果的调节器, 你输入一个参数,然后反馈给你一个同样类型的结果,代表了一个变化率,然后通过这个变化率来控制着每个时间片内滑动的距离。这个的实现我觉得需要考虑到手离开时的滑动速度,将要滑动的距离,滑动时间,摩擦因数等的,由于本人数学和算法都不太好,而且又长期写对算法要求不高的java,对这方面的研究不深入,最终也没能试出令自己满意的滑动效果,这里无法给出一个建议。目前我认为Android阵营中滑动效果最好的话可能就是某米的Launcher了(我指的是在不开启高质量绘图的情况下)最接近iOS的滑动体验,还有Go桌面也不错,LP的感觉滑动速度太快了,虽然可以调节,但是总感觉不爽。
好了就说这么多,我也不太确定M9的Launcher是在哪一方面还做的不够好,我也只是从技术角度大致分析了下造成滑动卡的原因,并无针对M9之意。希望煤油们了解Launcher优化的原理和难度,给工程师一点时间,确实一件事情要想做到极致不容易,但是我相信魅族会是这样的一个公司。希望魅族的Launcher越来越流畅,系统优化越来越好。"追求极致,专注细节",魅族有这样的风范,也希望魅族一如既往。
补充:
看了大家的回复,我感觉M9的卡可能不完全是我所说的这个方面(我仅玩过几回M9),M9关键可能是fps不高和滑动时fps不稳定,有人说是分辨率过高的原因,但是GalaxyTab(p1000)不是分辨率也那么高么(1024*600)?,用的和M9一样的蜂鸟CPU。我觉得他滑动起来还是不错的。之前的测评都表明M9的IO较差成为了系统瓶颈,如果M9的优化是受限于IO的性能而始终无法达到令人满意的程度的话,这似乎就感觉到是无解了— —!但是这又无法解释为什么装上第3方Launcher煤油又感觉流畅,所以总感觉在app层,Launcher还是有优化余地了,fps不高的话可能最主要的是View的drawcache的原因,drawcache这东西比较难控制了,什么时候创建,什么时候摧毁都需要慢慢尝试和优化,Android的UI绘制机制其实感觉挺复杂,反正我摸索了半个月左右没搞太明白,我对此也没有过多的经验,只是感觉是这是一个可努力的方向。然后还有绘图的质量,如果是因为绘图的质量的原因,我觉得是否可以提供一个开启和关闭高质量绘图的选项,虽然不能称之为一个完美的解决方案,但是可以满足一部分对于画质要求不高但是很注重流畅感的煤油。还有将背景设置为纯色也可以一定程度上提高滑动性能,不知道大家能不能接受?你看iPhone在前3代连壁纸都不能设置,背景黑黑的,人家照样卖的出去,说实话当年的硬件水平确实不行。我觉得CPU的硬件水平就是从ARM V7这代开始爆发的,而且发展越来越快,也许等到MX性能大提升就不卡了,但是软件的优化仍是必不可少的功课,也是魅族的核心竞争力。然后还有全屏绘制时设置 getWindow().getDecorView().setBackgroundDrawable(null);可以提高绘图性能这些小技巧不知道有没用上。这在官方文档里也是有说明的(android-sdk/docs/resources/articles/window-bg-speed.html)。先就这样,以后想到什么再说。如果我说错了,还请留言指教,大家交流交流。
|
|