如何读懂Framework源码?

首先,我也是一个应用层开发者,我想大部分有“如何读懂Framework源码?”这个疑问的,应该大都是应用层开发。

那对于我们来讲,读源码最大的问题,其实是没有应用场景,或者说短期来看成本高,收益底,容易半途而废

针对这个问题,首先是要要有一定的定力和研究精神,打算拿下哪部分的源码分析,即使遇到再多的问题,也要想办法解决,自己定的目标,跪着也要完成 其次,就是从什么方向入手,正如题主所说,源码很多,ndroid11的aosp整个下载下来,有150G左右,所以找入手点很重要,否则只会把源码下载完成之后就让它在硬盘里吃灰了

(上图为Android11的aosp源码大小)

针对应用层开发来讲,我这里提供几个面试比较常问,也比较容易上手的入手点

  1. 四大组件启动流程
  2. 应用启动流程
  3. 系统启动流程
  4. 音频相关内容

这里看上去的4个小点,其实真正做起来至少要半年的时间,因为里面涉及的内容既多又深,就第一点来讲,Activity启动流程就够你搞至少两周了,这里面会涉及ActivityThread ,AMS ,Zygote, Binder跨进程调用等一系列知识

这里再额外提一句,看到weishu大佬回答说不要关注各种流程的跟踪,其实我是不认同的,当然这只是小弟我基于自身知识和认知的看法

对于广大的应用层开发者也是一样,我们要明白自身的定位,小白走小白的路,大佬走大佬的路,个人认为,不论是跟各种系统流程的调用链也好,还是按系统服务去整块梳理也好,这些都是“过程”,而我们的目标,是深入framework源码,试问连调用链都没跟过,怎么深入源码?

当然,我也同意weishu大佬说的,要分析其后面涉及的思想和原理,但是这是第二层了,没有第一层的基础就想干第二层的事情,无异于空中楼阁,痴人说梦

回到正题上来,我们已经搞定了从什么地方入手,第二个要解决的问题是,我们需要具备什么样的基础,才能读懂源码,或者有能力去读源码

目前新版本的AOSP底层代码基本上都用C++重构过了,因此如果你想深入到native层,比如我们最常提到的handler,其实在native层也有一套实现,取消息的时候会通过管道机制进行唤醒通知,避免死等阻塞问题 那是不是说我们必须要先有C++或C语言基础才能去读源码呢?我认为,有基础自然好,没有也不会有太大影响,边度边补相关知识,可能比学完C++再来继续读源码效率要更高

因此,在我看来,不论你基础如何,只要有应用层开发经验,有探索和研究Framework的兴趣和欲望,这就够了。只要开始,就是进步

第三点我要讲的是,深入到什么程度是合适的。我在读源码的过程中,经常会跟着单个调用链越挖越深,比如在研究系统启动流程的时候,甚至到了虚拟机层面和汇编层面,但是一般来讲,我们不需要挖这么深,一来是没有必要,二来确实会花费大量精力,且很难见到成效

因此我在研究某个点的时候,会把这个点拆分成一个个的小问题,举一个具体的例子,在研究SystemServer相关流程的时候,我给自己提了这些问题

  1. SystemServer是如何被fork出来的
  2. SystemServer做了些什么事情
  3. SystemServiceManager是负责什么的?
  4. SystemServiceManager是如何创建的?
  5. ServiceManager是负责什么的?
  6. 启动服务有几种方式?他们之间有什么区别?
  7. SystemServiceManager和ServiceManager有什么区别?
  8. LocalService是负责什么工作的?
  9. SystemServer是服务端进程,那么谁是客户端进程?他们是如何通信的?内部机制是什么?(Binder相关的问题)

当然一上来可能提不出问题,或者不知道里面都涉及哪些重要的类,我们可以先阅读相关文章,有个大概的思路,此时就能提出一些基础的问题了,然后在阅读源码的过程中再不断提问和归纳。

第四点,我要提到的就是,要有正向反馈。很多人不是没有定力,但就是感觉读不下去,很大的原因就是没有正向反馈。我的正向反馈来自于我的文章产出,文章阅读量和博客关注度,以及和小伙伴们可以互相交流(但大多数时候,越深入的方向,可交流的人越有限)

我也建议大家在学习framework的时候可以多多交流,产出文章和成果,激励自己继续在这条路上走下去

第五点,需要提醒大家的是

如果你工作中有涉及相关内容(比如插件化,音视频,launcher,setting,AudioManger等),请优先研究相关源码

如果没有涉及,你可以参考我上面提到的入手点进行研究,只有你拥有了阅读和研究的能力,才能更好的完成更有挑战性的,甚至跨入Framework开发的行列当中

最后,在谈一谈阅读源码的好处吧,当你研究完一两个模块之后再来看,可能体会更深

正如weishu大神所讲,研究framework的好处并不在于记住了哪些调用流程,这些不是目的(但是确实必不可少的过程哦!),我们的目的是从更深的,或者说从更整体的视角来看我们的技术 比如四大组件是我们开发中最常用的,但fragment也是我们开发中常用的,为什么它不能称得上是“第五大组件”呢?

当我研究完四大组件的源码之后,我发现了四大组件最大的特点--支持跨进程,他们的启动流程都会涉及我的进程是否启动了,是否需要先跟zygote通信去fork出进程,然后再执行组件自身的启动逻辑 因此四大组件的重量级是很重的,而frament只是依赖于activity的的一部分,远达不到如此的重量级,因此也就自然不能成为“第五大组件”了

再说回来,阅读源码的好处

  1. 就是在于对应用层开发能理解的更深刻;
  2. 当遇到一些疑难问题的时候,我们有能力通过读源码去深挖问题的原因,并最终解决问题;
  3. 在于整体的阅读源码能力的提升,当我们在看其他三方库源码的时候,就会更得心应手了,连AOSP这个近200G的庞然大物都能搞定,Okhttp在它面前简直就是弟弟

最后

最后的最后,如果你打算开始读源码了,可以先看看我整理的这份资料。

《Android Framework精编内核解析》

本笔记讲解了Framework的主要模块,从环境的部署到技术的应用,再到项目实战,让我们不仅是学习框架技术的使用,而且可以学习到使用架构如何解决实际的问题,由浅入深,详细解析Framework,让你简单高效学完这块知识!

第一章:深入解析Binder

Binder机制作为进程间通信的一种手段,基本上贯穿了andorid框架层的全部。所以首先必须要搞懂的Android Binder的基本通信机制。Binder机制作为进程间通信的一种手段,基本上贯穿了andorid框架层的全部。所以首先必须要搞懂的Android Binder的基本通信机制。

本章知识点

  • Binder 系列—开篇

  • Binder Driver 初探

  • Binder Driver 再探

  • Binder 启动 ServiceManager

  • 获取 ServiceManager

  • 注册服务(addService)

  • 获取服务(getService)

  • Framework 层分析

  • 如何使用 Binder

  • 如何使用 AIDL

  • Binder 总结

  • Binder 面试题全解析

第二章:深入解析Handler

相信大家都有这样的感受:网上分析 Handler 机制原理的文章那么多, 为啥还要画蛇添足整理这份笔记呢?不是说前人们写的文章不好,我就是觉得他们写的不细, 有些点不讲清楚,逻辑很难通顺的,每次我学个什么东西时遇到这种情况都贼难受。

本章先宏观理论分析与 Message 源码分析,再到MessageQueue 的源码分析,Looper 的源码分析,handler 的源码分析,Handler 机制实现原理总结。最后还整理Handler 所有面试题大全解析。

Handler这章内容很长,但思路是循序渐进的,如果你能坚持读完我相信肯定不会让你失望。

第三章:Dalvik VM 进程系统

Andorid系统启动、init 进程、Zygote、SystemServer启动流程、 应用程序的创建使用,Activity的创建、销毁 Handler和Looper。

第四章 深入解析 WMS

窗口管理框架 系统动画框架 View的工作原理。

第五章 PackagerManagerService

包管理服务,资源管理相关类。

如有需要获取完整的资料文档的朋友点击我免费获取。

《Android 开发相关源码精编解析》

1.深入解析微信 MMKV 源码

MMKV 是微信于 2018 年 9 月 20 日开源的一个 K-V 存储库,它与 SharedPreferences 相似,但又在更高的效率下解决了其不支持跨进程读写等弊端。

2.深入解析阿里巴巴路由框架ARouter 源码

组件化被越来越多的Android项目采用,而作为组件化的基础——路由也是重中之重。因此详细的分析阿里巴巴开源的路由框架ARouter。从源码的角度解释为什么这样使用,以及避免做什么,让你使用地更加顺滑。

3.深入解析AsyncTask 源码(一款 Android 内置的异步任务执行库)

AsyncTask 是 Android SDK 中提供的一个用于执行异步任务的框架,在 Android 兴起的早期被广泛使用,但如今已经被 RxJava、协程等新兴框架所取代。虽然它存在着一些不足,但我们还是可以尝试了解一下它的实现原理以及存在的不足。

4.深入解析Volley 源码(一款 Google 推出的网络请求框架)

Volley 是 Google 开发的一款网络请求框架,目前已停止更新。虽然目前大家的关注焦点都在 Retrofit、OkHttp 等第三方网络请求框架,团队的项目中所用的也是这两个框架,但 Volley 中还是有非常多优秀的设计思想值得我们去学习的。

5.深入解析 Retrofit源码

在Andrroid开发中,网络请求十分常用,而在Android网络请求库中,Retrofit是当下最热的一个网络请求库。

6.深入解析OkHttp 源码

OkHttp是一个处理网络请求的开源项目,是Android端最火热的轻量级框架,由移动支付Square公司贡献用于替代HttpUrlConnection和Apache HttpClient。随着OkHttp的不断成熟,越来越多的Android开发者使用OkHttp作为网络框架。

7.深入解析ButterKnife 源码

作为 Android开发者,大家肯定都知道大名鼎鼎的butterknife。它大大的提高了开发效率,虽然在很早之前大家就开始使用它了,但是只知道是通过注解的方式实现的,却一直没有仔细的学习下大牛的代码。所以有必要系统的分析下 butterknife的实现原理。

8.深入解析Okio源码(一套简洁高效的 I/O 库)

Okio 中有两个非常重要的接口——Sink 以及 Source,它们都继承了 Closeable,其中 Sink 对应了我们原来所使用的 OutputStream,而 Source 则对应了我们原来所使用的 InputStream。

Okio 的入口就是Okio 类,它是一个工厂类,可以通过它内部的一些 static 方法来创建 Sink、Source 等对象。

9.深入解析SharedPreferences源码

SharedPreference 是一个 Android 开发自带的适合保存轻量级数据的 K-V 存储库,它使用了 XML 的方式来存储数据,比如我就经常用它保存一些如用户登录信息等轻量级数据。

10.深入解析EventBus 源码

EventBus 是一个 Android 事件发布/订阅框架。

传统的事件传递方式包括:Handler(消息处理机制,一般用于更新UI)、BroadCastReceiver(广播接收者)、Interface 回调。

EventBus优点:

  • Activity、Fragment、Service与线程之间的通讯是很常见的,EventBus正好可以屏蔽一些线程切换问题,简单地实现发布订阅功能。
  • 代码简洁,使用简单,并将事件发布和订阅充分解耦。

11.Android 自定义注解初探

由于之前用到的很多开源框架如 GreenDao、EventBus、ButterKnife、ARouter 等都使用了自定义注解,因此有必要去研究一下自定义注解。

12.View 的工作机制源码分析

13.Android 触摸事件分发机制源码分析

14.Android 按键事件分发机制源码分析

15.深入解析 Handler 源码

Android 的消息机制是基于 Handler 实现的。很多人以为,知道了 Handler、Looper、MessageQueue 就自以为了解了 Handler 的原理。但其实看源码的过程中慢慢就会发现,Handler 的内容可不止这点, 像同步屏障、 Handler 的 native 层的阻塞唤醒机制等等这些知识以前就没有理解清楚。

16.深入解析Binder源码

Binder在Android中堪称武林秘籍中的"易筋经",无论是菜鸟还是老鸟都对之神往。Binder架构是进程间相互通信的最常用手段,四大组件的基本功能都是依赖着Binder才能够实现的。

为了开发者能够使用java与cpp进行binder通信,binder的设计贯穿了framework、native和kernel层,开发者可以轻松的在上层使用binder向其它进程发起数据通信。

17.深入解析JNI源码

Android NDK开发中,常常因为效率、安全等原因,需要借助JNI的机制调用到Native环境中进行c/cpp操作。

18.深入解析Glide源码

Glide 功能丰富,图片三级缓存、可深度定制(继承AppGlideModule、LibraryGlideModule实现更多功能)、修改网络请求库、支持多种输入输出资源的转换(例如输入Stream,输出bitmap等等)、生命周期的管理。因此很有必要深入解析源码

19.RxJava原理及如何封装使用

RxJava可谓是Android开发人员必备技能,重要性就无需赘述了。

20.LeakCanary核心原理源码解析

LeakCanary是Android内存泄漏的框架,作为一个“面试常见问题”,它一定有值得学习的地方。

21.插件化架构定义及插件化架构的实践思路分析

babel插件、webpack插件、vue-cli插件,为啥这么多的优秀框架都是使用插件系统?插件化架构是什么?带来了什么好处?可以应用到什么场景呢?

如有需要获取完整的资料文档的朋友点击我免费获取。

如何读懂Framework源码?如何从应用深入到Framework?的更多相关文章

  1. 教你读懂vue源码技术教程

    由于 Vue 的源码采用 ES6,所以你至少应该掌握 ES6 才能看得懂,其次你最好对 package.json 中的字段的作用有所了解.由于 Vue 使用 Rollup 构建,所以你不了解 Roll ...

  2. 读懂react源码

    2019-11-06 1.最重要的两个目录,react,react-dom,(react-reconciler后续会很重要) 2.使用flow检查js的类型 3.react.createElement ...

  3. 金三银四助力面试-手把手轻松读懂HashMap源码

    前言 HashMap 对每一个学习 Java 的人来说熟悉的不能再熟悉了,然而就是这么一个熟悉的东西,真正深入到源码层面却有许多值的学习和思考的地方,现在就让我们一起来探索一下 HashMap 的源码 ...

  4. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

  5. 我快被Framework源码烦死了!

    前言 这段时间,忙到没时间学新东西,都有点心有余而力不足,想着抽空补补课,于是重读了Framework源码. 因为Framework源码太重要了,像掉帧监控.函数插装.慢函数检测.ANR 监控.启动监 ...

  6. Source Insight 基本使用(1)-使用Source Insight查看Android Framework 源码

    一.下载framework源码: google已经把framework源码托管在了gitHub上: https://github.com/android/platform_frameworks_bas ...

  7. (一)一起学 Java Collections Framework 源码之 概述

    . . . . . 目录 (一)一起学 Java Collections Framework 源码之 概述 JDK 中很多类 LZ 已经使用了无数次,但认认真真从源码级研究过其原理的还只占少数,虽然从 ...

  8. (二)一起学 Java Collections Framework 源码之 AbstractCollection

    . . . . . 目录 (一)一起学 Java Collections Framework 源码之 概述(未完成) (二)一起学 Java Collections Framework 源码之 Abs ...

  9. Django之REST framework源码分析

    前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...

随机推荐

  1. Custom Controller CollectionQT样式自定义 002 :NoteSlider 标签滑动条

    先上效果图 这个效果可以根据需求再定制,比如说文本框换成一个点下出现的气泡,跟随游标移动. 思路:继承QSlider,重写鼠标事件,添加label部件,定义其动作事件 源码:https://githu ...

  2. 3、dns服务搭建

    3.1.dns服务简介: 1.DNS(Domain Name System)域名系统. 目前提供网络服务的应用使用唯一的32位的IP地址来标识,但是由于数字比较复杂.难以记忆,因此产生了域名系统(DN ...

  3. SQL 小知识笔记

    1.自动生成序列号 select row_number() over(order by field1) as row_number,* from t_table

  4. 在Docker运行的Nignx内部署前后端分离项目

    环境准备: Linux服务器: IP: 192.168.1.10 前端打包后的Vue项目: Port-3000, 请求地址192.168.1.10:8080 后端打包后的Java项目: Port-80 ...

  5. sed 大括号 sed {} 的作用详解

    今天看别人写的脚本的时候,看到了sed  -r   {}   我看网上对于这个的记录比较少,所以就写了这篇随笔. 先看一下效果 cat  test.txt image: qqq/www/eee:TAG ...

  6. .NET Core授权失败如何自定义响应信息?

    前言 在.NET 5之前,当授权失败即403时无法很友好的自定义错误信息,以致于比如利用Vue获取到的是空响应,不能很好的处理实际业务,同时涉及到权限粒度控制到控制器.Action,也不能很好的获取对 ...

  7. angularjs的一点总结

    一,错误小结 1.出现类似于下面的错误,就是说明 $sessionStorage 这个服务未找到 Error: [$injector:unpr] Unknown provider: $sessionS ...

  8. bash的RANDOM变量生成的是真正的随机数吗

    static void seedrand () { struct timeval tv; gettimeofday (&tv, NULL); sbrand (tv.tv_sec ^ tv.tv ...

  9. buu yxx

    一.这题是南邮的题,异性相吸改编过来的,不过那题有给提示,这题没有233 不过做法确是一样的,winhex打开 直接异或,做法是一样的,直接对应的异或就可以了 a="lovelovelove ...

  10. Java | 日期类型的绍介和操作

    Date类 Date类在java.util.Date,Date类表示特定的瞬间,精确到毫秒.(毫秒是千分之一秒)毫秒可以对时间和日期进行计算,可以把日期转换为毫秒进行计算,计算完毕,再把毫秒转换为日期 ...