首先我們可以去這樣理解:(綜合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.lxweimin.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
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結構
我們可以看到系統基本在使用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
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。。。