yichao firstname, zeaster nickname, zhang lastname

tips on learning android

目前Android的源代码完全开放给了社区. 由于它的开放性, 易移植性, 它将不仅仅是一个手机操作系统, 近日社区中已经有人把Android移植到Asus Eee PC 1000H以及HP mini note 2133上. 其中蓝牙和无线也可以正常驱动.

可以预见的, Android将在更多的设备上生根发芽!

对于那些希望锻炼技术的同学们, Android的源代码是一个难得的学习机会!
整套Android源代码包括2部分, 一是platform部分, 另外一个是tools部分.
git://android.git.kernel.org/platform/manifest.git
git://android.git.kernel.org/tools/manifest.git

整个Android系统是由OHA各个厂商贡献的小系统组成的一个大系统.
Platform就是这个大系统, 目前它由16个核心系统, 61个外部系统, 21个内置的android应用程序或服务组成.每个小系统的功能简介可以参考http://source.android.com/projects

tools部分就是用来管理这些小系统的工具集, 可以方便小系统各自独立开发, 或者日后替换掉某个小系统, 又可以方便的把各个小系统集成到一起.
它包括了一个repo工具, 用来更方便的管理git代码库. 一个基于Rietveld的Gerrit代码review在线工具.

'''我很想知道这2个工具名字的来历?!
难度是为了纪念Gerrit Rietveld, 这位荷兰家具设计师?!
'''

啰唆了这么多, 才回到主题上, 学习android的tips,
一个tip就是善用这个Gerrit代码review在线工具. 通过它可以查看Android的code changes以及code review过程中的代码点评. 从中可以学习很多大师们的编程技巧. 所有open changes在这里
http://review.source.android.com/

比如change-6647, http://review.source.android.com/6647
是memcached以及MogileFS的作者Brad Fitzpatrick提交的. 他希望把系统是否在24小时模式这个boolean变量缓存下来,而不是每次都调用开销比较大的方法去判断.
这是代码的diff输出
http://review.source.android.com/6647/diff/1/za3656e3b0c4d095fd434b4c6a3dd70f07501f8f3
为了缓存这个boolean变量, Brad Fitzpatrick增加了2个static变量,
private static Context m24HourLastContext = null;
private static boolean mCached24HourMode;
但Code reviewer Romain Guy 不同意这次change, 原因也记录到了Gerrit上.
因为增加的static变量m24HourLastContext会造成内存泄露, 并且Romain给了一篇介绍类似内存泄露的blog.
http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/
在这篇blog中, 可以看到更多的Android实现细节. 比如android.graphics.drawable.Drawable对象由于callback方法而对其所属android.view.View的引用, 可以更加清晰的理解为什么Android平台上会出现这种内存泄露.
另外, Romain也说明了
(a)Android内置的Home Screen应用程序是如何解决Drawable对象对View的引用问题的.
(b)以及常见的2种避免类似内存泄露的方法.

Romain Guy这个同学也是个UI高手, 他学生时代在SUN参与了JDK中Swing的开发, 毕业后去了Google.

还有一些change可以反映出一些细节问题, 比如, http://review.source.android.com/6601
在Reviewer的评语中看到, 他要求能重用StringBuilder的地方绝不新建一个StringBuilder对象. 可见其对代码控制之严, 之细.
精致的软件就需要这样精致的控制.

以上这些仅仅是我看过5,6个chagnes后总结的, 相信如果阅读更多, 可以从中学习到更多的tips.

PS1,
Steve Guo同学的blog中有数十篇其工作中对android底层代码的分析, 值得推荐
http://letsgoustc.spaces.live.com/

PS2,
上面那个Dalvik中Drawable对象内存泄露的问题, 实际上是由于Dalvik默认就给Drawable增加了callback功能而引起的内存泄露.
由此联想到Sun的JDK中java.io.ObjectOutputStream的一个设计问题.
详见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4363937
其中也是由于ObjectOutputStream默认就认为其write的objects有依赖关系而将它们都保存到一个table中, 所以在传输大量对象时, 如果不间断的调用reset方法,就会导致OutOfMemoryError.
这些JVM设计者默认就给这些类设计了超级完备的功能, 而实际上大多数情况并用不上这些功能, 比如, drawable的callback功能, ObjectOutputStream输出对象的依赖关系.
如果默认使用最简单常用的功能, 而在特殊情况下, 由调用jdk的开发人员根据实际需要配置复杂的功能, 那么不仅可以提高运行效率, 也可以降低出现OutOfMemoryError的几率.
那么为什么他们还都要往复杂上设计?!

1 comment:

SurtaX said...

hi I've found your decompile dex file tutorial very useful. However I was wondering how I can decompile a file from the \res\xml folder? And how to edit the value and resign and repackage into apk?