Android插件化——基础知识

一、Binder原理

1、面向对象思想的引入将进程间通信转化为通过某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,而他的引用却遍布于系统的各个进程中。最诱人的是,这个引用和java里引用一样既可以是强类型也可以是弱类型,而且可以从一个进程传给其他进程,让大家都能访问同一个Server,就像将一个对象或引用赋值给另一个引用一样。Binder模糊了进程边界,淡化了进程间通信的过程,整个系统仿佛运行于同一个面向对象的程序中。

2、形形色色的Binder对象以及星罗棋布的引用仿佛粘结各个应用程序的胶水,这也是Binder在英文里的原义。

3、Binder分为Client和Server两个进程:Client和Server是两个相对的概念,可以简单理解为发消息的是Client,接收消息的事Server

4、Binder的通信模型:四个角色:Client、Service、ServerManager、Binder驱动。其中Server、Client、SMgr运行于用户空间,驱动运行于内核空间。这四个角色的关系和互联网类似:Server是服务器,Client是客户端,SMgr是域名服务器DNS,驱动是路由器。ServiceManager可以被比喻成电话局,存储着每个住宅的座机电话。张三给李四打电话,拨打电话号码,会先转接到电话局,电话局的接线员查到这个电话号码的地址,因为李四注册过,就能拨通;如果没注册,就会提示该号码不存在。

 

这里:ServerManager相对于Server来说,ServerManager是Server而Server是Client,而他们之间通信就像Server和Client一样,需要Binder驱动。

5、Binder的通信过程:

 

首先,Server进程要向SM注册,告诉自己是谁,自己有什么能力:Server告诉SM,他叫zhangsan,有一个object对象,可以执行add操作,于是SM建立了一张表,zhangsan这个名字对应进程Server;

然后,Client向SM查询:我需要联系一个名字叫做zhangsan的进程里面的object对象;这时候关键来了:进程之间通信的数据都会经过运行在内核空间里面的驱动,驱动在数据流过的时候做了一点手脚,他并不会给client进程返回一个真正的object对象,而是返回一个看起来跟object一模一样的代理对象objectProxy,这个objectProxy也有一个add方法,但是这个add方法并没有Server进程里面object对象的add方法的能力;objectproxy的add只是一个傀儡,他唯一能做的事情就是把参数包装然后交给驱动。

但是client进程并不知道驱动返回给他的对象动过手脚,CLient拿着objectproxy对象然后调用add方法,这个add什么也不做,直接把参数做一些包装然后直接转发给Binder驱动。

驱动收到这个消息,知道client使用的是proxy,他真正应该访问的是object对象的add方法;于是Binder驱动通知Server进程,调用你的object对象的add方法,然后把结果发给我,Server进程收到这个消息,照做之后将结果返回驱动,驱动然后把结果返回给Client,整个过程就完成了。

二、AMS

如果站在四大组件的角度看,AMS就是Binder中的Server,AMS(ActivityManagerService)从字面意思上看是管理Activity的,其实四大组件都归他管。

三、Activity工作原理

1、Activity是怎么启动的?——在手机屏幕上点击某个App图标,假设是斗鱼App,这个app首页就出现在我们面前了,这个操作背后经历了Activity和AMS反反复复的通信过程。

首先,在手机屏幕上点击App图标,手机屏幕就是一个Activity,而这个Activity所在的App,业界称之为Launcher,是各个手机厂商提供的。在开发App时,需要在AndroidManifest文件中定义默认启动Activity

<activity android:name=".MainActivity">

  <intent-filter>

     <action android:name="android.intent.action.MAIN"/>

     <category android:name="android.intent.category.LAUNCHER"/>

  <intent-filter>

</activity>

Launcher为每个app提供了启动这个app所需的intent信息,包括:

     action: android.intent.action.MAIN

     category: android.intent.category.LAUNCHER

     cmp:斗鱼的包名+首页Activity名

这些信息是App安装的时候,PackageManagerService从斗鱼的apk包的AndroidManifest文件中读取到的。

2、启动app并非那么简单

Launcher和斗鱼是两个不同的App,它们位于不同的进程中,它们之间的通信是通过BInder完成的——这时候AMS出场了。