Roman Guy的Android Trick系列文章笔记
Roman Guy是Android Framework的核心开发人员,从2009年开始,他在他的博客上发表多篇如何更好的开发android软件的文章(需要爬墙)。我的笔记的目的是把他这个系列的文章的核心内容总结起来。
?
第一篇.Faster Screen Orientation Change with Android
? ? 由于Android运行在很多个硬件上不同的设备上,并且的它们的硬件配置在运行时是可以的。例如,你推开手机的键盘,那么屏幕就会从portrait切换到landscape。为了让Android应用开发更容易一些,Android OS自动处理了配置的变化并且用新的配置重启了当前的activity。这是一个默认行为。如果你不了解Android如何处理资源,强烈推荐你看官方说明。
? ? 最好不要自行处理这些变化,否则不能保证你的代码在以后的更多的设备中运行。
? ? 文章介绍了一个很有用的Activity的api:?onRetainNonConfigurationInstance().?This method can be used to pass an arbitrary object your future self and Android is smart enough to call this method only when needed.
? ? ?他给出了两个代码片段:
?
?
很明显,后者节省了一个LinearLayout,如果这个是一个ListView的item的layout的话,那么这个节省就更加可观。
?
另外他提到:
?
The layout pass can be especially expensive when you nest several LinearLayout that use the weight parameter, which requires the child to be measured twice.?
?的确,在LinearLayout的源码中有相应的证明,参看LinearLayout#onMeasure(int widthMeasureSpec, int heightMeasureSpec)部分:如果child view的weight大于0,那么这个child view就会额外onMeasure一次。
?
总结语:UI是组织结构,配置的改变很容易引起连锁效应,我想Roman也是想告诉人们,要简单化你的UI,包括该文章后面的评论的一个例子:有人说他写了一个很棒的AbsouluteLayout,然后Roman回复说:
I don’t understand why it was so complicated for you to do this. Just a simple FrameLayout with margins would work fine.
所以对于UI乃至任何事情,复杂永远都是要避免的,否则你可能很轻易的被掉到沟里(试想你并不知道LinearLayout会怎么处理weight参数,而你写了一个有复杂LinearLayout嵌套的view,然后你发现你的view怎么这么慢,而你并不知道android正在努力的onMeasure啊)。
我自己的一个例子是,我之前写了一个组件,自定义UI,自己写了一个view,自己onMeasure,自己onLayout,结果后来,另外一个同事接受我的这个组建,然后他直接给改掉了,所有东西都用android自己的。不管效率问题,首先我这段代码在别人看来,是不好的,至少不易理解。如果我有足够的理由和数据来证明我的实现是OK的,那么我可以保证我的代码有更长的生命周期。
?
3.?Android Layout Trick #2: Include to Reuse
?
Android带来了各种各样的widget(small visual construction blocks you can glue together to present the users with complex and useful interfaces)。尽管application经常需要更高级的可视化组件。一个组件可被看作是由多个简单的既有的wdget组成的复杂widget。譬如你可以重用一个包含一个滚动条和一个button的panel,等等。。
?
In Android XML layout files, each tag is mapped to an actual class instance (the class is always a subclass of View.) The UI toolkit lets you also use three special tags that are not mapped to a View instance: <requestFocus />, <merge /> and <include />. The latter, <include />, can be used to create pure XML visual components.?
?
?
在这篇文章的评论处,有人提到使用include的文件和被include的文件之间引用ID的问题,他认为:
问题在于,included的views的id在include它们的文件里是不可见的,这种情况在多个included文件也存在。
Roman答道:
不,它们是可见的。
然后他又问道:
既然如此,那么为什么我引用included views的ID后,在编译的时候会出现:“Unknown resource”。
Roman答道:
IDs的声明和使用必须有正确的顺序。这跟你没有使用include是一样的。如果你要引用included layout里面的ID,那么你要使用@+id或者把把id声明在values/目录内。引用一个included layout外部的id,同样要使用@+id
?
总之include标签可以让layout得到重用,它的一些细节可以用到的时候再仔细看。
?
4.?Android Layout Tricks #3: Optimize, Part 1
?
The
<merge />was created for the purpose of optimizing Android layouts by reducing the number of levels in view trees. ?文章通过一个示例来解释这个标记的功能。?
尽管merge标记很有用,但是它仍然受到一些限制:
a)<merge />只能被用作XML layout的root标记。
b)如果你通过Inflater来创建layout的话,你必须指定一个ViewGroup并且必须设置attachToRoot为true(详见inflate())