Android Framework 如何学习,如何从应用深入到Framework?

看了深入理解安卓1,看到第7章,看了安卓源码情景分析,看到日志那章,还看了一点安卓内核剖析,看着看着就看不动了,现在又拐回来看应用,关于系统方面的书前面讲原理的比较多,以至于工作中感觉接触到AMS,PMS,电源服务还没看到,就不想看了,我还没有跳读的习惯,每本书都想从头看到尾,但又限于水平有限,很多都不能充分理解,看着看着就看不动了,应用的层的书籍又很少涉及Framework方面的知识,就感觉应用的时候实现难度还…
关注者
2009
被浏览
72454
谢邀,不太赞同最高票的答案。

Android的功夫,在Android之外。
这句话我很认同,Android Framework只不过是对底层系统的封装,要想深入理解它,必须熟悉JNI、读得懂C++、理解Java虚拟机、Linux系统甚至汇编、指令集等等。但是,这并不意味着想要理解Android Framework就必须熟悉这些东西!逆命题与原命题并不是等价的。等你学完上述那些知识,Android说不定已经黄了(当然如果你真的掌握了这些,下一代操作系统是什么已经不重要了)举个例子,回想一下你小时候学习说话的时候,大人教你会先教你语法吗?我可以肯定世界上所有的语言教育都不会这么做,大家都是先教你喊爸爸妈妈,进而一些简单的词汇,然后一些简单的句子,等你都熟练了,再让你学习语法,一样的道理。对于一个有一定语言知识的人,也是一样,你学英语的时候,也是先学习how are you, I am fine, thank you的吧?如果一个领域对你来说是全新的,你就硬着头皮去打基础,有了一定的认知,再去通过你的元认知能力去深入学习。所以,我觉得不要等到万事俱备的时候才去做某一件事,一旦决定去做,天亮就出发。

另外,我不觉得那些讲源码的书有多烂;要想搞清楚一个系统的构架、设计以及当时碰到的问题以及做出的抉择,恐怕只有系统的设计者才能讲的清楚;据我所知,按照这个观点只有《C++的设计与演化》才能算得上所谓的「好书」。那些写书写博客的人,作为传经布道者,很有可能也无法理解某些设计——很多抉择都是处于当时的特殊场景以及历史原因;但是这并不妨碍他们给你讲解这方面的知识。在看《深入理解XXX》这种书的时候,我有两个经验:
  1. 不要记那些所谓的API调用链,哪里调用了哪里,又从哪里跳转到了哪里;根本没用,而且你也记不住。你要思考以及关心的是,作者是怎么跟踪调用的?一个上千行的函数体,作者是如何知道哪里是下一个关键入口的?比如从Java的native函数,如何找到正确的C++实现?一个Binder Client的调用,怎么知道他的Server在哪里?然后你自己可以尝试跟踪一下,看看自己会不会跟丢;如果你可以做到,那么你差不多就可以自己分析源码了。
  2. 既然你记不住细节,那么你就需要理解,需要思考;想一想这里为什么这么做,这样实现是优雅还是谬误,如果是你,你怎么做?当然,并不是所有的地方都需要这样,那些没有味道的代码,还是略过吧。把它当作参考书;自己理解一遍之后,再碰到这种问题,直接翻书,不要自己跟了浪费时间。
简单总结一下就是,看那些讲源码的书或者博客的时候,除非你要了解某个细节,那么不要过于关心那些复杂的函数调用链,学习跟踪方法以及把握整理流程最为重要。Android源码树异常庞大,如果你想一行不漏地看,不可能;就算你这么干了,效果也不见得好——只见树木,不见森林。打个简单的比方,Activity的启动流程,你不用关心在AMS里面这里跳到那里是干什么,还有ActivityStack以及它的那个SuperXX跳来跳去是在搞毛,你需要了解的是:在Context里面,通过AMS的Client ActivityManagerNative发起Binder调用进入system_server进程,在AMS里面绕了一圈(处理Activity栈以及生命周期相关),然后通过IApplicationThread这个Binder调用回到App进程的Binder线程池,在线程池里面通过Handler发送Message到App主线程,最终通过ClassLoader加载Activity类,创建对象,回调对应的生命周期,整个过程结束。

作为一个过来人,我很认同 @Van Bruce Android的功力在Android之外这个观点;同时作为一个初学者,我也相信,要了解Android Framework也没有想象中的那么难。

扯了这么多,来正面回答一下这个问题吧。

先纠正题主几个错误:

1. 「没有跳读的习惯,每本书都想从头看到尾」这个是绝对错误的,技术书与文学等其它类别的书籍不同,你没有必要每一章都看,必须纠正这个习惯。第一,不是所有的书每一章每一节每一段每一句都是精华,花时间去看那些价值不大的,就是浪费时间;而且,越到后面,你需要掌握的知识以及要看的书也越来越多,个人压根儿没有精力也不可能全部看完;挑一些重点的,自己感兴趣的看就可以了,如果你不知道什么是重点,向前辈请教或者来知乎这种地方提问就行。
2. 「很多都不能充分理解,看着看着就看不动了」,这个也是不对的。没有人能够一看就懂,一学就会。都是一点点理解、摸索然后再融会贯通的;一次不理解没有关系,多看几次,慢慢就有感觉了。犹记得我当初不理解Binder,老罗的博客,《Binder设计与实现》还有源代码,我前前后后完整地看了不下六遍;熟能生巧,如果你能把书中看到的,自己思考的,源码里面学到的这些散落的东西连成串,有了自己感觉,那么前面就是通途了。

-------------------------------手动分割-------------------------------------

如何学习Android Framework?路只有一条:Read the f*cking source code。至于如何「平稳」过渡,其实我觉得学习曲线并没有那么陡峭——Android Framework的代码不也是代码?不理解是因为没有整体把握而已。

不论是看书,看博客,你的最终目的只有一个「学会看源码」,而不是「学会源码」。关于如何阅读源码,这不是一个简单的问题,我有几点经验:
  1. 看不懂的多读。上面已经说过了,没有人一学就会;特别是对于初学者,你刚看系统源码,肯定一头雾水;万事开头难,在你觉得艰深晦涩的时候,你就当在背课文;Android Framework的代码时遵循一定规范的,你在背了一篇课文之后,再去读别的课文,读到一半的时候就算你看不懂,很有可能你就会知道下面要讲什么了,虽然下面要讲的你也不懂。背熟了之后,你就可以想每一句是什么意思了;而这里面的「段落」、「句子」不就是普通的代码吗?就这样,一步一步串联起来,聚沙成塔,积少成多,就水到渠成了。「书读百遍,其义自现」讲的就是这道理。如果你真的想要学习Framework,一定要多读,硬着头皮读,不要放弃,否则都是扯淡。
  2. 不重要的少读。看不懂的很容易知道是什么,那么怎么知道哪些代码是不重要的呢?这里有两层意思:其一,强调的是大局观,在初学习一个模块的时候,你需要先把握整体,再了解局部;这个场景下,所有的细节都是不重要的。其二,那些真正不重要的逻辑;你刚学习的时候肯定没有办法知道哪些是影响不大的逻辑,所以你需要跟着书籍,博客,让前人带路;如果跟着它们的脚步走通了这条路,那你就自己独立走一遍,这时候你肯定会走丢,然后你跟踪、尝试,接着到达终点;这时候你自然就知道,哪些重要,哪些不重要。
  3. 边读边思考。学而不思则罔,思而不学则怠。带着问题去阅读源码,这里是什么意思?为什么需要这么做?这样的实现是优雅还是俗套?有没有更好的实现办法?如果我来写,我会怎么写?诸如此类,有了思考就有了自己的理解。
  4. 不是所有的都需要思考。接上条,Framework的代码也是人写的,有精华,自然有糟粕,也有食之无味的。你不用对着每一段代码都问个十万个为什么。一个问题通常有很多种解决方案,当时的设计者选择目前这种实现,有兼容问题有历史原因,还有它自己的理解;不是所有的实现在现在看来都是很好的实现,所以,追问这些问题很多时候都没有意义,不要过度解读。举个例子,Android的IPC机制为什么用Binder?也许有人说,Socket不安全,效率不够高;共享内存使用不方便,等等。但是你去看看这个问题:为什么 Android 要采用 Binder 作为 IPC 机制? - Android 开发 你就知道,很多时候并没有那么多为什么。
  5. 记得做笔记。做笔记的重要性在于,它可以记下你自己在某个阶段自己的理解,当你更进一步的时候回头再看当初的理解,想想哪里是对的,哪里又有问题,这是一个相当有意思的过程。我想每一个人在看自己之前写的代码,都会有在某个地方觉得自己是沙比的时候。根据你学习过程简单总结一下,这样你的元认知能力就得到了提升。
最后自荐一下我的博客:Weishu's Notes 里面有我对于Binder以及Framework的理解和学习过程,一定会有帮助 ^_^ 至于其它细节问题,可以参考一下我其他的答案。

最后,文明交流,拒绝撕逼。