首先我们可以去这样理解:(综合ActivityManagerService和ApplicationThread分析)
凡是在源码中和binder有关的最底层的抽象类都会去extends Binder并且实现Ixxxxxxx接口
就比如我们可以看到ActivityManagerService继承的ActivityManagerNative就是最底层的抽象类。
我们可以看到
public abstract class ActivityManagerNative extends Binder implements IActivityManager
再比如ApplicationThread(注意这个类是在ActivityThread中定义的一个内部类)继承的ApplicationThreadNative也是最底层的抽象类,我们可以看到
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
OK,那么问题来了,还有的Service呢?跟AMS齐名的PMS呢,怎么不拿出来分析一下呢,来我们去看看PMS是怎么玩的?
public class PackageManagerService extends IPackageManager.Stub
也就是说IPackageManager.Stub应该是PMS的最底层的抽象类,于是乎我们就去苦苦追寻这个IPackageManager.Stub东西了,结果你会发现你完!!全!!找!!不!!到!!
不要慌,让老夫领你去看个究竟。
源码的编译
实际上,如果源码里面翻多了,你会发现不单单是这个东西,很多东西都是没有的,飘红的。实际上android sdk manager帮我们下载的相应的api版本下的source文件都不是android的系统源码,只能满足你初步的查看,如果你真的想要去把源码看个究竟,单单通过sdk目录下的source是不够的,你需要做的是编译源码http://www.jianshu.com/writer#/notebooks/6954184/notes/8031957
改变源码的阅读方式
我们现在再次去看看能不能找得到IPackageManager,结果一搜就搜到了
public interface IPackageManager extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager {
.....
}
...
}
我们看到这个Stub内部类也是extends 了Binder并且实现了IPackageManager
包括之前同样看不到的WindowManagerService继承的IWindowManager(就是我们常说的WMS)也是一模一样的。
为什么一开始找不到
为什么AMS可以找得到,是因为AMS的Binder相关都是直接定义在源码中的,区别于其他服务的定义,我们可以很清楚的看到AMS继承的ActivityManagerNative是直接定义在源码中的,而这个AMN就相当于后面出现的Stub,后面出现的IPackageManger或者是IWindowManager都是通过aidl的方式去生成的,都是我们通过编译源码的方式生成的,此处如果对aidl不了解可以去了学习一下aidl的知识。
Binder的结构(此处分别以AMS和PMS进行分析)
-
AMS
最最根部的是接口IActivityManager,这个接口定义了AMS所有需要用到的服务的方法,并且需要继承IInterface,我们可以把他理解为一个叫I的接口,因为所有的binder的东西都是跟这个前缀叫I的东西有关的,这个IInterface定义了一个asBinder的方法,可以把所有继承这个IInterface的类统统转化成IBinder。
/**
* Base class for Binder interfaces. When defining a new interface,
* you must derive it from IInterface.
*/
public interface IInterface
{
/**
* Retrieve the Binder object associated with this interface.
* You must use this instead of a plain cast, so that proxy objects
* can return the correct result.
*/
public IBinder asBinder();
}
OK,我们继续往上一层看
ActivityManagerNative继承了Binder而Binder实现了IBinder这个接口,我们暂且不去分析这两个类事干什么用的,只需要知道跟binder机制有关系。
那么既然AMN最终实现了IBinder这个接口,又继承了IActivityManger这个类,那么上面所说的adBinder这个方法直接返回其本身就可以了,果不其然。
public IBinder asBinder() {
return this;
}
但是当我们在这个类中搜索asBinder这个方法的时候我们却发现实现的不止一处,还有一处也实现了这个方法,
public IBinder asBinder()
{
return mRemote;
}
结果看到还有个代理类ActivityManagerProxy,于是乎就很好奇的去ctrl+G了。发现来自与ActivityManagerNative的方法asInterface:
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*/
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
我们看到注释已经写的相当明白了,把一个Binder对象转换成Activity Manager接口,如果有必要的话搞一个Activity Manager的代理出来。我们把其中的两个方法逐个击破,首先是obj.queryLocalInterface,这个是IBinder的方法:
/**
* Attempt to retrieve a local implementation of an interface
* for this Binder object. If null is returned, you will need
* to instantiate a proxy class to marshall calls through
* the transact() method.
*/
public IInterface queryLocalInterface(String descriptor);
其实就是要去获得这个binder接口的本地实现,上面也说了,如果获取不到,需要通过搞一个代理出来,直接看这个接口方法还是比较难理解这玩意儿到底是干嘛的,那我们就去找一找什么地方使用到了这个asInterface方法,全局一下(此处真的体会到导入源码的重要性),发现有三处调用,我们只看重要的一处:
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
这个是用的非常平凡的方法,ActivityManagerNative的gDefault变量,实际上就是维护这一个IActivityManager的单例,我们看到这个IBinder b是来自于ServiceManager的serviceMap(这个之前看过一点binder的服务注册的应该都会知道),但是我之前一直不知道到底是什么时候把activityManagerservice这个东西注册进去的,现在有了源码了,找了一下,果然就找到了,在ActivityManagerService中有这么一个方法,里面把AMS自生注册到了ServiceManager中:
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
....
}
....
}
....
}
我们看到传的是this,这个时候我们终于要去点开那个神器的queryLocalInterface方法了,看看它是怎么实现的:
/**
* Use information supplied to attachInterface() to return the
* associated IInterface if it matches the requested
* descriptor.
*/
public IInterface queryLocalInterface(String descriptor) {
if (mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
很明显,做了一个字符串匹配,如果相同就把mOwner返回出去,我们在Binder.java中找到了这两个变量的定义:
public void attachInterface(IInterface owner, String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
然后我们又在ActivityManagerNative中找到了这个方法的调用:
public ActivityManagerNative() {
attachInterface(this, descriptor);
}
String descriptor = "android.app.IActivityManager";
水落石出了吧,捋一捋逻辑之后我们发现,实际上最初的那个queryLocalInterface方法,实际上就是去对穿进来的binder最一个教研,看这个binder是不是AMS,如果是AMS那么就去把它转换成IActivityManager,如果不是那么就搞一个ActivityManagerProxy代理出来。其实这里面就涉及到一个问题,大家会不会觉得这个queryLocalInterface方法永远都是有效的呢,其实不然,这里就要涉及到跨进程的东西了,在单进程中去理解事没有问题的,但是跨进程的时候就会有问题了,这里其实我们可以从ActivityManagerProxy的构造函数能够看的出来:
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
private IBinder mRemote;
这个传进来的remote就是另外一个进程的binder,那么我们如何去理解呢?
queryLocalInterface这个方法实际上真正的用途是去判断一下,这个binder是否是在当前的进程,如果不在,那么就去搞一个代理,如果在当前进程,就直接把它转成IActivityManager进行使用(因为服务真正的方法都定义在了IActivityManager这个接口里面,那么转成接口就可以直接去使用它的方法了)。
抛开底层Binder不谈的整个framework层的IPC交互流程
我们在这里停一下,先来看一下整个涉及到binder的类的结构(以AMS和PMS这两个典型为例)
-
AMS
我们可以看到系统基本在使用AMS的时候直接使用的是ActivityManagerNative.getDefault()去做调用,就跟标注的一样,如果AMS服务就在当前的进程中那么直接调用ActivityManagerService中的相应方法。如果不在一个进程中,那么就调用Proxy的方法,就要涉及到使用IPC通信了,我们可以看到Proxy的方法都会涉及到mRemote.transact方法,然后在远程进程的继承ActivityManagerNative的AMS会首先触发onTransact方法,并在onTransact中去调用相应的请求方法。
我们以AMS的startActivity方法为例:
(1) 如果在一个进程中,那么直接就去调用AMS的startActivity方法:
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
(2) 如果不在一个进程中,那么就先去调用ActivityManagerProxy的startActivity方法:
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
然后在另外一个进程中的ActivityMangerService接收到了transact请求,触发了onTransact方法(这个方法定义在了基类ActivityManagerNative中:
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
String resultWho = data.readString();
int requestCode = data.readInt();
int startFlags = data.readInt();
ProfilerInfo profilerInfo = data.readInt() != 0
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
...
}
}
我们看到会在onTransact方法中再去调用AMS中的startActivity方法。
基本frameWork级别的都是直接调用的ActivityManagerNative.getDefault()去处理的,而我们平时需要使用到AMS的服务的时候都是直接去使用ActivityManager的相应方法的(当然只会局限于部分方法,因为AMS里的大部分方法我们是用不到的),比如getDeviceConfigurationInfo方法:
/**
* Get the device configuration attributes.
*/
public ConfigurationInfo getDeviceConfigurationInfo() {
try {
return ActivityManagerNative.getDefault().getDeviceConfigurationInfo();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
很明显了,我们所使用到的ActivityManager实际上就是对ActivityManagerNative的一个封装,把常用的方法放出来给用户使用。
-
PMS
与AMS有几点不同:
(1)没有了类似于ActivityManagerNative这样的类,凡是使用aidl文件生成的Binder文件都是这样的结构,在IPackageManager中定义了内部类Stub和Proxy,分别对应ActivityMangaerNative和ActivityManagerNative.ActivityManagerProxy.
(2) PackageMange是一个抽象类,具体的实现在ApplicationPackageManager中,而我们平时直接去使用PackageManger都是直接在Activity中调用getPackageManager:
@Override
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
我们可以看到IPackageManger来自与 ActivityThread.getPackageManager():
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
//Slog.v("PackageManager", "default service binder = " + b);
sPackageManager = IPackageManager.Stub.asInterface(b);
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
而返回的PackageManger是new ApplicationPackageManager(this, pm)
ApplicationPackageManager(ContextImpl context,
IPackageManager pm) {
mContext = context;
mPM = pm;
}
然后我们平时使用PackageManager的方法实际上都是类似于如下的调用:
@Override
public ActivityInfo getActivityInfo(ComponentName className, int flags)
throws NameNotFoundException {
try {
ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId());
if (ai != null) {
return ai;
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
throw new NameNotFoundException(className.toString());
}
至此FrameWork层的Binder基本吃透,TBC。。。