前言

如果你最近在找工作或者有关注Android行业的招聘这一块就会发现,现在很多公司,特别是大厂在招聘高工或者架构师的时候都会将熟悉framework原理或源码列为招聘要求之一。那么作为一个Android开发者是否都要去学习framework呢?又该如何去学习呢?我们今天来聊一聊Framework开发的那些事。

为何需要学习framework

系统应用开发,现在来说,已经开始脱离系统,单独拿出来开发,系统定制接口,已提供给应用调用,用来增强功能。原生的桌面,拨号,设置,已经没法做出差异化优势,因此都费尽心机,来进行应用深度开发对于之前维护系统应用模块的人来讲,修修补补,真的没有什么成长。对个一个Android开发者来说,每天的工作如果没有很深的技术壁垒,就很容易被别人攻陷,最后被公司和市场给“优化”掉。

就好比如设置、联系人、再小的改动,修改故障的时候,没有非常高的要求,做过应用开发的,都可以过来参和一脚,改改问题。而让一个应用开发得去修改系统接口,估计改的心累,并且犹豫不决。所以这时候你需要一层技术壁垒,来增强自己的核心竞争力。也只有拥有核心竞争力,并持之以恒的学习,扩充自己的深度,广度,那么不管是在怎样的一个市场环境下,你的位置都牢不可破,不会轻易被替代,这也是为什么我觉得Android开发者需要学习framework的原因。

framework如何学习

Framework的核心技术

接下来博主从自身的角度,讲讲系统应用开发,该如何向framework进军,进行学习,掌握更加核心的技术。

这里有人会说,我做应用风生水起,也游刃有余,不比你们做系统Framework的差,何必把系统应用开发的贬的一文不值。这里要说一下,文中没有这个意思,你的应用做的有声有色,赚的盆满钵满,这里肯定有其因素。比如它的性能,它的界面绚丽,百变主题。或者它有智能识别,等等。这些都叫做差异化产品,有其亮点,特色,才能杀出重围。

而系统应用开发,我这里偏向于手机整机开发中的OEM厂商,主要做出系统,能够保证功能正常,不会花费大量人力精力去做应用深度开发,系统重构的。这里主要会以追求速度,同时满足客户的硬件要求,比如多个霍尔器件,多个温度传感器,多个皮套功能,等等,但很少去大量改动应用架构,以免影响最终量产。

以上,就是特指的这个应用开发人员。随后,我来讲讲,Framework需要掌握哪些知识呢?

操作系统

熟悉我的人都知道,我特喜欢把这个放在第一位,原因很简单,它确实支撑了我随后的所有知识根基,让我能够从容不迫的,将一个个系统拆解出来。

我们就拿安卓来讲,启动过程

Android 启动过程框架

跟linux如出一辙,所以很容易迁移过来,同时,差异化的init进程,完成初始任务,创建安卓世界的孵化器,既然这里要进入安卓世界,而安卓世界的基础语言是java,那么就需要一个Java虚拟机,于是孵化器就要构造一个虚拟机,用来解析执行Java编译出来的字节流。而孵化器本身是由c cpp语言实现,于是Java虚拟机就是由c cpp语言写出来的,linux操作系统也是c(还有一些汇编)写出来的,于是Java虚拟机运行的Java语言,就需要跟c cpp打交道,于是就有了JNI。

孵化器做了几件事情:

  1. 完成Java虚拟机的构造

  2. 完成JNI对接Java与c的桥梁

  3. 加载公共的共享库

  4. 等待别人给它发消息,创建新进程

在这期间,孵化器要做一件事情,便是创建system_server ,这个进程要做什么呢?我们创建了一个可以运行Java的虚拟机,这时我们就要提供一堆系统接口,用来协助应用开发,比如请求网络啦,比如创建界面啦,比如定位啦,获取存储卡啦,等等支持,方便用户开发功能。一个平台的好坏,往往取决于它的功能是否强大,是否有丰富的技术文档,以及开发调试工具。

所以就有了一堆线程,比如AMS,WMS,PMS,BT,WIFI,这些都可以在/proc/{ system_server_pid}/ tast找到记录。

有了这些线程,那么我们就可以轻松的去实现很多功能啦。这时我们就要配套的开发工具,比如AS编辑器,可以编辑,编译出来APK,安装到手机运行。

关于操作系统,需要掌握的知识点为:

  1. 进程,线程概念

  2. 互斥,死锁机制与原理,如何避免死锁

  3. 内存管理机制,虚拟内存

  4. 静态库与动态库的区别

  5. 进程之间的内存屏障,如何通信(IPC)

  6. binder的通信优势

这里先想到这些,注意不是要完成懂所有机制,要的是整体理解即可。如下问题,请思考下,看是否能够答上来。

如果我写了一个应用,名字叫做,com.codegg.home 在主activity里面,加载一个布局,layout_main. xml,布局里面写入了一个TextView,那么我想调试这个TextView,要在com.codegg.home这个进程下断点,还是在system_server进程下断点呢?如果是想调试ActivityThread. java的话?应该在哪个进程下断点呢?

以上答案,都是com.codegg.home下断点,原因是这两个当前的运行进程,都是在com.codegg.home里,所以要调试的话,要在com.codegg.home进程下断点。

那么我们再来思考下,我现在要去追应用的启动过程,start Activity的流程,要在哪个地方下断点呢?

我们知道这个流程,最终核心的都在Activity manager server里面,而它是在system server进程里面,以一个线程的状态存在,于是我们要调试,就要在system server上面下断点了。

搞清楚了system server后,以我们熟悉的AMS WMS PMS 举例。这些服务线程,完成应用的请求任务,将结果返回给应用。比如查看当前运行的所有Activity,就是应用发起请求,从操作系统那里,先找到server manager,这个手里拿到一堆服务的句柄,也可以说令牌,你只能通过这个找到它。

当server manager一看你有权限,就帮你把对应的AMS的句柄给你,这个句柄操作系统也认识,对应到system server的AMS引用上,也就是你通过这个句柄,调用它的方法,操作系统就会将你的请求,传递到system server中去,同时操作系统知道这个句柄是AMS的第20号(这个20号代表查询当前运行的所有Activity的方法),然后就唤醒system server,同时从binder线程池,这个线程跟AMS一样,是个线程,从线程池拿出一个,调用AMS的20号方法。

调用完成后,从操作系统层面,把数据交给调用的应用,实现数据传输。这里面定义的传递数据格式是包裹,也就是序列化数据。

了解进程通信

好了,这块就说这么多,主要是说下进程通信,以及binder这种通信的简单逻辑。这里说下,为什么要通信。

因为操作系统设计,管理的软件单元是进程,进程间本身不联系,彼此看不见。一个进程想跟另一个说话,他两都认识的人是操作系统。因为他们是由操作系统管理的。操作系统通过从硬盘将程序装载进入内存,同时给每一个分配了进程号,于是他们就都在系统里面有了标记,同时每个都起了名字,一个叫我就喜欢吃,一个叫我就喜欢喝。喜欢喝的一个人孤单,他不认识喜欢吃的,他就问操作系统,有没有人喜欢吃的,操作系统一查,说有啊,然后把喜欢吃的的进程号给他,他就可以找到喜欢吃的了。

然后操作系统给他了一辆车,让他把想给喜欢吃的的东西,装在车上寄过去。这个车子是操作系统提供的,这个车子就是通信方式。比如汽车,飞机,步行。

于是进程间的通信方式就是,从操作系统找到目标,然后拿到通信方式,用操作系统给的通信工具,进行通信。

数据结构和算法

这块完成了,我们再来讲一个内容:

文件=文件头+文件内容

我们发现,这里MP3格式,OGG格式,都属于一个文件的格式声明,这个我们可以用HEX工具打开MP3文件,可以看到刚开始的位置,这块属于描述后面的内容该如何解析,比如文件名字,文件大小,文件格式,系统根据这个描述,尝试用对应的解码器解码,解码完成后进行播放。

这里解码器如何解码,就是算法。而文件头,就是描述这个文件的数据结构。

于是,我们就知道

程序=数据结构+算法

比如我要写个贪吃蛇,如何描述蛇的状态,长度,当前轨迹,这些都是需要表征出来,然后围绕着这个描述内容,进行操作,这块就属于算法。

完成的程序,运行起来,就是进程。所以进程是一个存在于内存的东西,操作系统用一个表格记录进程数据,比如进程号,父类进程,进程打开的文件句柄,进程当前状态,进程的上下文(上下文是保存当前CPU的寄存器,保存现场用的,因为寄存器是只有一份,当一个进程被打断时候,另个进程运行,那么之前的就要把它当前的寄存器存下来,防止被别人盖掉,等到下次自己运行的时候,再恢复回来,保证自己运行正常),程序是存在硬盘或者其他存储设备,掉电不会丢失,而进程是内存的,所以掉电就不再了。

程序如何加载,系统如何识别的呢?这就又回到开头的地方,数据结构加算法,也叫文件头和文件内容。源码经过编译链接,变成一个文件,我们亲切的叫它可执行文件。那么我们来说说它。

我们常见的两种可执行文件,windows上面称为PE格式,linux称为ELF,两者都是从COFF格式演化来的,这块参考《链接器与加载器》,喜欢感兴趣,可以下载阅读此书。

程序是如何在CPU执行的?

那么有了格式描述,操作系统就知道如何解析它了,然后把对应的代码段,数据段,堆栈区域配置好,将代码装载进入内存中,然后将下一条执行位置,也就是PC寄存器,指向这个可执行文件配置的text 入口,这个就是程序的入口点,这个我们去写的main方法,可以简单理解成入口,实际情况是在这个前面,系统加入了一些代码,为运行此程序做准备,准备OK才会真正调用到main方法,这段代码叫创建此进程的环境,比如参数,堆栈初始化。

聊到这里,我们从别的纬度,再来看看。

数字电路的与或非逻辑电路,开启了新世界的大门。我们用断点,通电,表示两个状态。我们不能说,好像有电,好像没电,所以,计算机的世界,定义了二进制,因为是非可以界定,孰是孰非不好界定。

于是,在我们的电路板上,规定了0-0.6V,代表了没电,4.4-5V,代表了有电,中间的数值,代表了器件的错误,不稳定性。

于是没电用0表示,有电用1表示,实际世界就是两个区间电压。

CPU在石英晶振的推动下,执行一条条指令。指令是什么呢?就是一串串数字,每一串代表一个具体含义。

所以,CPU能够执行多少条指令,是考量它是否强大的一个重要参数,另一个是它执行一天指令的时间,也叫指令周期,越短越好。也就是两个CPU同时做一个加法,谁用时短谁就强。

CPU拿到一条指令,就会在石英晶振的推动下,将这条指令执行完,然后将PC寄存器加1,读取下一条指令。

我们经常遇到的非法指令,就是因为CPU拿到了一个不认识的数据串,导致异常。比如它的指令集里面,有加法,有减法,你给他说你给我翻个跟头(非法指令),他骂了一句去你的吧,老子不会(异常报错)。一般这种情况是指令不识别,比如你用了新的arm指令,又在旧的arm板子运行这个程序,就会挂掉,提示非法指令。

刚开始的操作系统,嵌入式的操作系统,是没有做内存保护,就是程序段可以跳到数据段执行,当然现在加入了内存管理单元,会将数据段内存描述成可读可写不可执行,如果PC(程序寄存器)指向了这个地方,去读取执行的时候,就会报非法访问。

如果没有保护,你去读取数据段的数据,作为指令执行,出现指令异常就太正常了。

好了,由于篇幅原因,今天就给大家介绍这么多,综上希望能让朋友们意识到作为一个Android开发者对于学习framework的重要性,如果想更系统的学习framework,请接着往下看。

最后

想要更系统的学习framework的朋友,博主我最近在GitHub上找到一份腾讯T4大佬整理的,已标星8k的Android Framework开发笔记,今天拿出来分享给大家,需要的伙伴麻烦点赞+任意评论后,点击这里获取!

本笔记主要讲解了Framework的主要模块:

第一章: 深入解析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

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

需要《framework精编内核解析》完整PDF文档的伙伴麻烦点赞+任意评论后,点击这里获取!

更多相关文章

  1. (转帖)Android开发者应该如何推广营销自己的应用程序
  2. Android(安卓)源码编译AIDL 使用实例讲解及Android(安卓)Studio
  3. Android靠哪些东西能打败iphone
  4. Android中的任务,进程,线程以及服务
  5. Android(安卓)点九图机制讲解及在聊天气泡中的应用
  6. 一看就懂的Android(安卓)APP开发入门教程
  7. Android(安卓)如何改变应用图标
  8. Building Your First App(创建你的第一个应用程序)
  9. (20120722)(笔记004)android开发应用程序资源

随机推荐

  1. android之软键盘管理
  2. Android之SlidingDrawer滑动抽屉
  3. android中自定义view构造函数ContentItem
  4. android Intent打开URL链接
  5. Retrofit2使用方式和源码解析
  6. Android一键拍照功能
  7. as&vscode生成key及打包android
  8. android http请求并解析返回的xml
  9. android获取设备屏幕大小的方法
  10. Android开启关闭手机扬声器