写给Android App开发人员看的Android底层知识(1)
这个系列的文章一共8篇,我酝酿了很多年,参考了很多资源,查看了很多源码,直到今天把它写出来,也是战战兢兢,生怕什么地方写错了,贻笑大方。
(一)引言
早在我还是Android菜鸟的时候,有很多技术我都不太明白,也都找不到答案,比如apk是怎么安装的,比如资源是怎么加载的。
再比如说,每本书都会讲AIDL,但我却从来没用过。四大组件也是这个问题,我只用过Activity,其它三个组件,不但没用过,甚至连它们是做什么的,都不是很清楚。
之所以这样,是因为我一直从事的是电商类App开发工作,对于这类App,基本就是由列表页和详情页组成的,所以我们每天面对的是Activity,会写这两类页面,把网络底层封装的足够强大就够了。
绝大多数App开发人员,都是如此。
但直到接触Android的插件化编程和热修复技术,才发现只掌握上述这些技术是远远不够的。
(二)还是引言
市场上有很多介绍Android底层的书籍,网上也有很多文章,但大都是给ROM开发人员看的,动辄贴出几页代码,不适合App开发人员去阅读学习。
我曾经在微信中问过老罗和老邓,你们写的书为什么我们App开发人员看不懂啊,他们就呵呵了,跟我说,他们的书就是写给ROM开发人员看的。
于是,这几年来,我一直在寻找这样一类知识,App开发人员看了能有助于他们更好的编写App程序,而又不需要知道太多这门技术底层的代码实现。
这类知识分为两种。
一种是知道概念即可,就比如说Zygote,其实App开发人员是不需要了解Zygote的,知道有这么个东西是“孕育天地”的就够了,类似的还有SurfaceFlinger、WMS这些概念。
还有一种是需要知道内部原理,就比如说Binder。关于Binder的介绍铺天盖地,但对于我们App开发人员,需要了解的是它的架构模型,只要有Client和Server,以及SM就足够了。
四大组件的底层通信机制都是基于Binder的,我们需要知道每个组件中,分别是哪些类扮演了Binder Client,哪些类扮演了Binder Server。知道这些概念,有助于我们App开发人员进行插件化编程。
(三)目录
我这个系列的文章,已经写好了下面的内容,会在接下来的每天发布一篇,共计8篇,看了这8篇文章,就可以迈进Android插件化的大门了。
- Binder
- AIDL
- AMS
- Activity
- Service
- ContentProvider
- 匿名共享内存
- BroadcastReceiver
- PMS及App安装过程
Android底层知识,还应该包括以下内容,但是和插件化关系不大,也不是我擅长的领域,所以我只列出了大纲,没有继续写下去:
- View和ViewGroup
- Message、Looper和Handler
- 权限管理
- Android SDK工具内部原理
有兴趣的同学,可以按照我这个思路继续写下去,记得,一,少贴代码。多画图,二,一定要有趣。
接下来就详细讲那些App开发人员需要知道的Android底层知识。
(三)Binder
Binder是为了解决跨进程通信。
关于Binder的文章实在是太多了,每篇文章都能从Java层讲到C++层,App开发人员其实是没必要了解这么多内容的。我们看对App开发有用的几个点:
1)首先,Binder分为Client和Server两个进程。
注意,Client和Server是相对的。谁发消息,谁就是Client,谁接收消息,谁就是Server。
举个例子,两个进程A和B之间使用Binder通信,进程A发消息给进程B,那么这时候A是Binder Client,B是Binder Server;进程B发消息给进程A,那么这时候B是Binder Client,A是Binder Server——其实这么说虽然简单了,但还是不太严谨,我们先这么理解着。
2)其次,我们看下面这个图(摘自田维术的博客),基本说明白了Binder的组成解构:

图中的IPC就是进程间通信的意思。
图中的ServiceManager,负责把Binder Server注册到一个容器中。
有人把ServiceManager比喻成电话局,存储着每个住宅的座机电话,还是很恰当的。张三给李四打电话,拨打电话号码,会先转接到电话局,电话局的接线员查到这个电话号码的地址,因为李四的电话号码之前在电话局注册过,所以就能拨通;没注册,就会提示该号码不存在。
对照着Android Binder机制,对着上面这图,张三就是Binder Client,李四就是Binder Server,电话局就是ServiceManager,电话局的接线员在这个过程中做了很多事情,对应着图中的Binder驱动
3)接下来我们看Binder通信的过程,还是摘自田维术博客的一张图:

注:图中的SM也就是ServiceManager。
我们看到,Client想要直接调用Server的add方法,是不可以的,因为它们在不同的进程中,这时候就需要Binder来帮忙了。
- 首先是Server在SM这个容器中注册。
- 其次,Client想要调用Server的add方法,就需要先获取Server对象, 但是SM不会把真正的Server对象返回给Client,而是把Server的一个代理对象返回给Client,也就是Proxy。
- 然后,Client调用Proxy的add方法,SM会帮他去调用Server的add方法,并把结果返回给Client。
以上这3步,Binder驱动出了很多力,但我们不需要知道Binder驱动的底层实现,涉及到C++的代码了——把有限的时间去做更有意义的事情。
App开发人员对Binder的掌握,这些内容就足够了。
是时候总结一波了:
- 学习Binder,是为了更好的理解AIDL,基于AIDL模型,进而了解四大组件的原理。
- 理解了Binder,再看AMS和四大组件的关系,就像是Binder的两个进程Server和Client通信。
(四)AIDL
AIDL是Binder的延伸。一定要先看懂我前面介绍的Binder,再来看AIDL。要按顺序阅读。
Android系统中很多系统服务都是aidl,比如说剪切板。举这个例子,是为了让App开发人员知道AIDL无处不在,和我们距离非常近。
AIDL中需要知道下面几个类:
- IBinder
- IInterface
- Binder
- Proxy
- Stub
当我们自定义一个aidl文件时(比如MyAidl.aidl,里面有一个sum方法),Android Studio会帮我们生成一个类文件MyAidl.java,如下图所示:

MyAidl.java这个生成文件中,包括MyAidl接口,以及Stub和Proxy两个实现了MyAidl接口的类,其中Stub是定义在MyAidl接口中的,而Proxy则定义在Stub类中。
我曾经很不理解,为什么不是生成3个文件,一个接口,两个类,清晰明了。都放在一个文件中,这是导致很多人看不懂AIDL的一个门槛。其实Android这么设计是有道理的。当有多个AIDL类的时候,Stub和Proxy类就会重名,把它们放在各自的AIDL接口中,就必须MyAidl.Stub这样去使用,就区分开了。
对照这张图,我们继续来分析,Stub的sum方法是怎么调用到Proxy的sum方法?然后又调用另一个进程的sum方法的?
起决定意义的是Stub的asInterface方法和onTransact方法。其实这个图没有画全,把完整的Binder Server也画上,就应该是这样:

1)先从Client看起,对于AIDL的使用者,我们这么写程序:
MyAidl.Stub.asInterface(某IBinder对象).sum(1, 2); //最好在执行sum方法前判空。
asInterface方法的作用是判断参数——也就是IBinder对象,和自己是否在同一个进程:
- 是,则直接转换、直接使用,接下来就跟Binder跨进程通信无关啦;
- 否,则把这个IBinder参数包装成一个Proxy对象,这时调用Stub的sum方法,间接调用Proxy的sum方法。
return new MyAidl.Stub.Proxy(obj);
2)Proxy在自己的sum方法中,会使用Parcelable来准备数据,把函数名称、函数参数都写入_data,让_reply接收函数返回值。最后使用IBinder的transact方法,把数据就传给Binder的Server端了。
mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0); //这里的mRemote就是asInterface方法传过来的obj参数
———————我是Binder分界线—————-
3)Server则是通过onTransact方法接收Client进程传过来的数据,包括函数名称、函数参数,找到对应的函数,这里是sum,把参数喂进去,得到结果,返回。
所以onTransact函数经历了读数据-->执行要调用的函数-->把执行结果再写数据的过程。
下一篇文章要介绍的四大组件的原理,我们都可以对照着AIDL的这张图来看,比如说,四大组件的启动和后续流程,都是在和ActivityManagerService(简称AMS)来来回回的通信,四大组件给AMS发消息,四大组件就是Binder Client,而AMS就是Binder Server;AMS发消息通知四大组件,那么角色就互换。
那么四大组件中,比如说Activity,又是哪个类扮演了Stub的角色,哪个类扮演了Proxy的角色呢?这也是我下一篇文章要介绍的,包括AMS、四大组件各自的运行原理。
好戏即将开始。
写给Android App开发人员看的Android底层知识(1)的更多相关文章
- 写给Android App开发人员看的Android底层知识(2)
(五)AMS 如果站在四大组件的角度来看,AMS就是Binder中的Server. AMS全称是ActivityManagerService,看字面意思是管理Activity的,但其实四大组件都归它管 ...
- 写给Android App开发人员看的Android底层知识(6)
(十一)BroadcastReceiver BroadcastReceiver,也就是广播,简称Receiver. 很多App开发人员表示,从来没用过Receiver.其实吧,对于音乐播放类App,用 ...
- 写给Android App开发人员看的Android底层知识(3)
(七)App启动流程第2篇 书接上文,App启动一共有七个阶段,上篇文章篇幅所限,我们只看了第一阶段,接下来讲剩余的六个阶段,仍然是拿斗鱼App举例子. 简单回顾一下第一阶段的流程,就是Launche ...
- 写给Android App开发人员看的Android底层知识(5)
(十)Service Service有两套流程,一套是启动流程,另一套是绑定流程.我们做App开发的同学都应该知道. 1)在新进程启动Service 我们先看Service启动过程,假设要启动的Ser ...
- 写给Android App开发人员看的Android底层知识(7)
(十二)ContentProvider (1)ContentProvider是什么? ContentProvider,简称CP. 做App开发的同学,尤其是电商类App,对CP并不熟悉,对这个概念的最 ...
- 写给Android App开发人员看的Android底层知识(8)
(十)PMS及App安装过程 PMS,全称PackageManagerService,是用来获取Apk包的信息的. 在前面分析四大组件与AMS通信的时候,我们介绍过,AMS总是会使用PMS加载包的信息 ...
- 写给Android App开发人员看的Android底层知识(4)
(八)App内部的页面跳转 在介绍完App的启动流程后,我们发现,其实就是启动一个App的首页. 接下来我们看App内部页面的跳转. 从ActivityA跳转到ActivityB,其实可以把Activ ...
- 一看就懂的Android APP开发入门教程
一看就懂的Android APP开发入门教程 作者: 字体:[增加 减小] 类型:转载 这篇文章主要介绍了Android APP开发入门教程,从SDK下载.开发环境搭建.代码编写.APP打包等步骤 ...
- 谋哥:App开发人员的苦逼不值得怜悯!!
[谋哥每天一干货,第四十篇] 为什么取这个标题呢?由于昨天一些本来"支持"谋哥的人看到谋哥搞收费VIP群,认为谋哥赚苦逼开发人员的钱非常不道德,且说谋哥我写的东西都 ...
随机推荐
- 大数据测试之hadoop集群配置和测试
大数据测试之hadoop集群配置和测试 一.准备(所有节点都需要做):系统:Ubuntu12.04java版本:JDK1.7SSH(ubuntu自带)三台在同一ip段的机器,设置为静态IP机器分配 ...
- AngularJS1.X学习笔记4-内置事件指令及其他
AngularJS为我们定义了一系列事件指令,方便我们对用户的操作作出响应.甚至他还有一个可选模块提供了触摸事件和手势事件的支持,为移动端开发提供了可能.现在开始学习一下AngularJS的事件指令. ...
- 创建你的第一个webdriver python代码
前言 今天我们开始我们的第一个python webdriver自动化测试脚本.并就测试脚本进行一一解释说明. webdriver python代码 本示例代码演示了使用Ie浏览器访问百度进行搜索测试. ...
- 实用开发之-oracle表回滚到一个指定时间的操作语句
在开发或客户使用过程中,难免会出现误操作或脏数据,那么怎么迅速处理这个问题呢? 1.备份还原就用了,太麻烦. 就是使用ORACLE的备份功能,然后在还原,还原的时候新建一个库,然后使用dblink进行 ...
- spring+mybatis事务不起作用的原因
一.场景再现 @Override @Transactional public void updateById(String userId,String username) throws Excepti ...
- python作业设计:多级菜单,并可依次进入各级子菜单
'''作业三:多级菜单 三级菜单 可依次选择进入各子菜单 所需新知识点:列表.字典 ''' data = { "北京":{ "昌平":{ "沙河&qu ...
- UPS电源效果及有关名词解析
UPSuninterruptpowersystem缩写,4.工频机和高频机<工频机UPS选用工频变压器作为整流器和逆变器的部件的UPS电源:高频机是以高频开关元件代替整流器和逆变器中粗笨的工频变 ...
- mysql性能优化配置总结
看了一些优化mysql运维的一些书籍,在此记录总结下:进入mysql客户端输入以下sql:1.连接设置 show variables like '%max_connection%'; show sta ...
- STM32学习笔记(一)——点亮一个LED
引言 最近报名了2017全国大学生电子设计竞赛,我们学校是第一次参加这个比赛,由于8/9月份就要比赛了,所以现在准备是比较晚的了,指导老师说只能做控制类的题目了,让我们学习一下STM32单片机,51到 ...
- java多线程基本概述(七)——join()方法
在很多情况下,主线程创建并启动子线程,如果子线程中有大量的耗时运算,主线程将早于子线程结束,如果想让主线程等待子线程结束后再结束,那么我们可以使用join()方法.调用join()方法的意思是当前线程 ...