轉(zhuǎn)載請(qǐng)注明出處:http://blog.csdn.net/callon_h/article/details/52073268
引子上一篇博客從內(nèi)核驅(qū)動(dòng)到android app講述了android通過(guò)框架層訪問(wèn)到硬件的方法。
這一篇博客,承接上一篇,來(lái)講述其訪問(wèn)硬件的第二種方法中涉及的binder的知識(shí)(其實(shí)不止是硬件服務(wù),后面大家會(huì)看到)。
有人看過(guò)上一篇博客源碼的可能問(wèn),從上篇給的源碼中完全沒(méi)有看到binder相關(guān)的東西,那么在此先貼一段代碼,慢慢講:
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/core/java/android/os/ILedService.aidl
*/
package android.os;
/** {@hide} */
public interface ILedService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.ILedService
{
......
}
public int LedOpen() throws android.os.RemoteException;
public int LedOn(int arg) throws android.os.RemoteException;
public int LedOff(int arg) throws android.os.RemoteException;
}
看到這里有的朋友可能想起來(lái)了,這是我們之前用ILedService.aidl自動(dòng)生成的ILedService.java,路徑其實(shí)上一篇說(shuō)過(guò)了,只是代碼沒(méi)貼。
那么其中最重要的Stub類(lèi)它繼承(extends)于Binder并且還實(shí)現(xiàn)(implements)了android.os.ILedService里的接口。
這里就引出了我們的主角Binder,它是android源碼分析中的重中之重。
簡(jiǎn)單地說(shuō),Binder是Android平臺(tái)上的一種跨進(jìn)程交互技術(shù)。
從實(shí)現(xiàn)的角度來(lái)說(shuō),Binder核心被實(shí)現(xiàn)成一個(gè)Linux驅(qū)動(dòng)程序,并運(yùn)行于內(nèi)核態(tài)。這樣它才能具有強(qiáng)大的跨進(jìn)程訪問(wèn)能力。
在Linux系統(tǒng)里面,進(jìn)程之間是相互隔離的,也就是說(shuō)進(jìn)程之間的各個(gè)數(shù)據(jù)是互相獨(dú)立,互不影響,而如果一個(gè)進(jìn)程崩潰了,也不會(huì)影響到另一個(gè)進(jìn)程。這樣的前提下將互相不影響的系統(tǒng)功能分拆到不同的進(jìn)程里面去,有助于提升系統(tǒng)的穩(wěn)定性,畢竟我們都不想自己的應(yīng)用進(jìn)程崩潰會(huì)導(dǎo)致整個(gè)手機(jī)系統(tǒng)的崩潰。而Android是基于Linux系統(tǒng)進(jìn)行開(kāi)發(fā)的,也充分利用的進(jìn)程隔離這一特性。
這些Android的系統(tǒng)進(jìn)程,從System Server 到 SurfaceFlinger,各個(gè)進(jìn)程各司其職,支撐起整個(gè)Android系統(tǒng)。而我們進(jìn)行的Android開(kāi)發(fā)也是和這些系統(tǒng)進(jìn)程打交道,通過(guò)他們提供的服務(wù),架構(gòu)起我們的App程序。那么有了這些進(jìn)程之后,問(wèn)題緊接著而來(lái),我們?cè)趺春瓦@些進(jìn)程合作了?答案就是IPC。
Linux System 在IPC中,做了很多工作,提供了不少進(jìn)程間通信的方式,下面羅列了幾種比較常見(jiàn)的方式。
Signals 信號(hào)量Pipes 管道Socket 套接字Message Queue 消息隊(duì)列Shared Memory 共享內(nèi)存按照復(fù)用的角度上看,既然有這么多”輪子”后,就應(yīng)該合理利用這些”輪子”,從而方便地調(diào)用系統(tǒng)服務(wù)。然而事實(shí)并沒(méi)有這么簡(jiǎn)單,Android系統(tǒng)作為嵌入式的移動(dòng)操作系統(tǒng),通信條件相對(duì)更加苛責(zé)一些,苛責(zé)的地方提現(xiàn)在:拮據(jù)的內(nèi)存,移動(dòng)設(shè)備上的內(nèi)存情況不同于PC平臺(tái),內(nèi)存受限,因而需要有合適的機(jī)制來(lái)保證對(duì)空閑進(jìn)程的回收Android 不支持System V IPCs安全性問(wèn)題顯得更為突出,移動(dòng)平臺(tái)特有的權(quán)限問(wèn)題需要Death Notification(進(jìn)程終止的通知)的支持
由于前面提及的特殊性,先前的輪子已經(jīng)不能滿(mǎn)足所有的需求了,因而Android上就有了 Binder。 Binder 是一個(gè)基于OpenBinder開(kāi)發(fā),Google在其中進(jìn)行了相應(yīng)的改造和優(yōu)化,在面向?qū)ο笙到y(tǒng)里面的IPC/組件,適配了相關(guān)特性,并致力于建立具有擴(kuò)展性、穩(wěn)定、靈活的系統(tǒng)。
但盡管如此,跨進(jìn)程調(diào)用還是受到了 Linux 進(jìn)程隔離的限制,而解決方案就是將其置于所有進(jìn)程都能共享的區(qū)域 –Kernel,而 Binder Driver 提供的功能也就是讓各進(jìn)程使用內(nèi)核空間,將進(jìn)程中的地址和Kernel中的地址映射起來(lái),其中Linux ioctl 函數(shù)實(shí)現(xiàn)了從用戶(hù)空間轉(zhuǎn)移到內(nèi)核空間的功能。在
Binder Driver 的支持下,就能實(shí)現(xiàn)跨進(jìn)程調(diào)用。
Binder架構(gòu)包括服務(wù)器接口、Binder驅(qū)動(dòng)、客戶(hù)端接口三個(gè)模塊。
Binder服務(wù)端(Server):一個(gè)Binder服務(wù)端實(shí)際上就是Binder類(lèi)的對(duì)象,該對(duì)象一旦創(chuàng)建,內(nèi)部則會(huì)啟動(dòng)一個(gè)隱藏線程,會(huì)接收Binder驅(qū)動(dòng)發(fā)送的消息,收到消息后,會(huì)執(zhí)行Binder對(duì)象中的onTransact()函數(shù),并按照該函數(shù)的參數(shù)執(zhí)行不同的服務(wù)器端代碼。onTransact函數(shù)的參數(shù)是客戶(hù)端調(diào)用transact函數(shù)的輸入。
Binder驅(qū)動(dòng)(Driver):任意一個(gè)服務(wù)端Binder對(duì)象被創(chuàng)建時(shí),同時(shí)會(huì)在Binder驅(qū)動(dòng)中創(chuàng)建一個(gè)mRemote對(duì)象,該對(duì)象也是一個(gè)Binder類(lèi)??蛻?hù)端訪問(wèn)遠(yuǎn)程服務(wù)端都是通過(guò)該mRemote對(duì)象。
客戶(hù)端(Client):獲取遠(yuǎn)程服務(wù)在Binder驅(qū)動(dòng)中對(duì)應(yīng)的mRemote引用,然后調(diào)用它的transact方法即可向服務(wù)端發(fā)送消息。
作為架構(gòu)先了解到這,然后我們先來(lái)通過(guò)上一篇的Led的例子來(lái)理解架構(gòu)。
首先附上詳細(xì)的ILedService.java程序并加以說(shuō)明:
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/core/java/android/os/ILedService.aidl
*/
package android.os;
/** {@hide} */
public interface ILedService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.ILedService
{
private static final java.lang.String DESCRIPTOR = "android.os.ILedService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an android.os.ILedService interface,
* generating a proxy if needed.
*/
public static android.os.ILedService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.ILedService))) {
return ((android.os.ILedService)iin);
}
return new android.os.ILedService.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_LedOpen:
{
data.enforceInterface(DESCRIPTOR);
int _result = this.LedOpen();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_LedOn:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _result = this.LedOn(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_LedOff:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _result = this.LedOff(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements android.os.ILedService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public int LedOpen() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_LedOpen, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public int LedOn(int arg) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(arg);
mRemote.transact(Stub.TRANSACTION_LedOn, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public int LedOff(int arg) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(arg);
mRemote.transact(Stub.TRANSACTION_LedOff, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_LedOpen = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_LedOn = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_LedOff = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
}
public int LedOpen() throws android.os.RemoteException;
public int LedOn(int arg) throws android.os.RemoteException;
public int LedOff(int arg) throws android.os.RemoteException;
}
只要細(xì)心一點(diǎn)一定能找到客戶(hù)端Client需要的class Proxy還有服務(wù)端Server需要的class Stub,其實(shí)它們都在這一個(gè)文件中。
而為什么我能說(shuō)客戶(hù)端需要的是Proxy而不是Stub?或者說(shuō)為什么服務(wù)端需要的是Stub而不是Proxy?
原因1. 我們先把注意力集中到Proxy類(lèi)中的
@Override public int LedOpen() throws android.os.RemoteException
這個(gè)方法上(其實(shí)LedOn和LedOff也是一樣的),它調(diào)用了一句:
mRemote.transact(Stub.TRANSACTION_LedOpen, _data, _reply, 0);
接下來(lái)我們看Stub類(lèi)的
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_LedOpen:
{
data.enforceInterface(DESCRIPTOR);
int _result = this.LedOpen();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_LedOn:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _result = this.LedOn(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_LedOff:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _result = this.LedOff(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
細(xì)節(jié)我們可以不深究但是至少我們能夠得到這樣一個(gè)結(jié)論:我們的Proxy類(lèi)transact了一個(gè)TRANSACTION_LedOpen“消息”,而Stub類(lèi)中的onTransact可以來(lái)通過(guò)switch響應(yīng)這個(gè)“消息”,并且調(diào)用我們真正在LedService.java上實(shí)現(xiàn)的
public int LedOpen() throws android.os.RemoteException;
方法。
原因2. 我們來(lái)看LedService這個(gè)類(lèi)到底是繼承自誰(shuí)?
public class LedService extends ILedService.Stub
原因3. ?Proxy意為代理人,Stub意為票根。
總結(jié)一下(1圖取自文章4,2圖取自文章5),個(gè)人覺(jué)得用圖的方式總結(jié)是最好的:
該圖中的Proxy為之前所述的ILedService.Stub.Proxy,Stub為ILedService.Stub,Client你可以認(rèn)為是調(diào)用
iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));
的app,而Service則可以認(rèn)為是LedService。而上圖是我們正常的service訪問(wèn)流程圖,正常的service一般都含有IBinder mBinder對(duì)象和OnBind()方法,而在app的activity端有onServiceConnection()對(duì)應(yīng)之,其中g(shù)etPid()對(duì)應(yīng)于我們的LedOpen()等AIDL定義的接口方法。這些都只是框架,如果要到代碼層分析還需要了解一些Binder中的概念。
BpBinder——Binder中的代理方對(duì)應(yīng)類(lèi),C++語(yǔ)言描述,繼承自IBinder
BBinder——Binder中響應(yīng)方對(duì)應(yīng)類(lèi),C++語(yǔ)言描述,繼承自IBinder
BpInterface——進(jìn)程并不直接和BpBinder(Binder代理)打交道,而是通過(guò)調(diào)用BpInterface(接口代理)的成員函數(shù)來(lái)完成遠(yuǎn)程調(diào)用的
BnInterface——BnInterface是繼承于BBinder的,它并沒(méi)有采用聚合的方式來(lái)包含一個(gè)BBinder對(duì)象
ProcessState——在每個(gè)進(jìn)程中,會(huì)有一個(gè)全局的ProcessState對(duì)象,ProcessState的字面意思就是“進(jìn)程狀態(tài)”,當(dāng)然應(yīng)該是每個(gè)進(jìn)程一個(gè)ProcessState
我們通過(guò)前一篇博文可以看到,要完成LedService還需要的重要一步是注冊(cè)進(jìn)ServiceManager
led = new LedService();
ServiceManager.addService("led", led);
由ServiceManager統(tǒng)一管理,而client進(jìn)程與這些Service通信時(shí),首先需要向ServiceManagerService中查找相應(yīng)的Service,拿到返回值后再將返回值轉(zhuǎn)成對(duì)應(yīng)的接口,就可與對(duì)應(yīng)的Service進(jìn)行通信了,也就是我們?cè)赼pp中使用的語(yǔ)句
iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));
這里會(huì)涉及到一個(gè)問(wèn)題:ServiceManagerService本身就是一個(gè)單獨(dú)的進(jìn)程,客戶(hù)端必須先跨進(jìn)程與ServiceManagerService交互之后才可與自己需要的Service進(jìn)行交互。解決的辦法為:將ServiceManagerService的handle(每一個(gè)Service的唯一標(biāo)識(shí))設(shè)置為0,這樣就可以拿到SMS在本進(jìn)程中的代理對(duì)象了(c層中直接new的一個(gè)BpBinder(0)對(duì)象,這拿到的就是SMS的代理對(duì)象)。但對(duì)于別的Service而言,不能采用該種方法,因?yàn)樗鼈兊木浔蒘MS控制,不一定是固定的。
ServiceManagerService類(lèi)似于DNS服務(wù)器,每一臺(tái)pc都會(huì)向dns服務(wù)器中查詢(xún)自己無(wú)法解析的域名對(duì)應(yīng)的ip地址,然后使用拿到的ip地址進(jìn)行訪問(wèn)。而client首先向ServiceManagerService查詢(xún)自己需要的Service的handle(相當(dāng)于ip),然后才跟對(duì)應(yīng)的Service通信。而
ServiceManager.getService("led")
就相當(dāng)于從dns查詢(xún)ip的過(guò)程,我們首先分析它:
public final class ServiceManager {
private static final String TAG = "ServiceManager";
private static IServiceManager sServiceManager;
private static HashMap sCache = new HashMap();
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
/**
* Returns a reference to a service with the given name.
*
* @param name the name of the service to get
* @return a reference to the service, or null
if the service doesn't exist
*/
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
...
...
}
getService會(huì)在緩存中找我們name對(duì)應(yīng)的service,找不到就調(diào)用getIServiceManager()拿到我們的ServiceManager Service,然后通過(guò)getService拿到我們的IBinder對(duì)象
再往下分析,首先看getIServiceManager()實(shí)際上調(diào)用了
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
繼續(xù)找到asInterface
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
/**
* Cast a Binder object into a service manager interface, generating
* a proxy if needed.
*/
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
...
}
asInterface最后返回的是IServiceManager的子類(lèi)ServiceManagerProxy,所以我們的getIServiceManager().getService(name)就相當(dāng)于ServiceManagerProxy(obj).getService(name),其中obj就是我們的BinderInternal.getContextObject(),再往下
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
...
}
其中,我們的mRemote就是我們的BinderInternal.getContextObject(),我們把它的代碼找到
/**
* Return the global "context object" of the system. This is usually
* an implementation of IServiceManager, which you can use to find
* other services.
*/
public static final native IBinder getContextObject();
從注釋中可以看出getContextObject是一個(gè)native方法,它拿到的是一個(gè)整個(gè)系統(tǒng)的context object,并且經(jīng)常是IServiceManager的實(shí)現(xiàn)類(lèi),通過(guò)它你可以找到其他的services,即它就是管理所有services的ServiceManagerService,如果還想往下分析,需要找到我們的android_util_Binder.cpp:
// ----------------------------------------------------------------------------
static const JNINativeMethod gBinderInternalMethods[] = {
/* name, signature, funcPtr */
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
從名字上也知道android_os_BinderInternal_getContextObject是我們需要的:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
繼續(xù)看b對(duì)象具體是什么
sp ProcessState::getContextObject(const sp& caller)
{
return getStrongProxyForHandle(0);
}
getStrongProxyForHandle又是什么
sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
在這里我們就會(huì)發(fā)現(xiàn),其實(shí)我們得到是BpBinder,所以ProcessState::self()->getContextObject(NULL)其實(shí)就是BpBinder(0)
這里的參數(shù)為什么是0呢?之前我也提到了,0指的就是我們ServiceManager的binder對(duì)象,這個(gè)是唯一的,所以javaObjectForIBinder(env, b)也就是javaObjectForIBinder(env,BpBinder(0)),接著我們不再貼長(zhǎng)代碼分析,沒(méi)有意義,得出結(jié)論比較重要:
1. 分析javaObjectForIBinder,它返回的是jobject javaObjectForIBinder(JNIEnv* env, const sp
2. gBinderProxyOffsets在int_register_android_os_BinderProxy中我們可以找到答案
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
...
gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
...
}
從這里我們可以看出gBinderProxyOffsets其實(shí)就是android/os/BinderProxy我們的java類(lèi),也就是我們上面返回的是一個(gè)BinderProxy,BinderProxy是什么呢,一會(huì)我們會(huì)講到,也就是說(shuō)BinderInternal.getContextObject()我們最終得到是BinderProxy,也就是我們ServiceManager中的ServiceManagerNative.asInterface(BinderInternal.getContextObject());其實(shí)就是ServiceManagerNative.asInterface(BinderProxy);也就是getIServiceManager().getService(name);其實(shí)就是ServiceManagerNative.asInterface(BinderProxy).getService(name)。所以我們就又回到ServiceManagerProxy類(lèi)中的getService了,也就是
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
我們的mRemote其實(shí)就是BinderProxy類(lèi),所以它的transact就是BinderProxy的transact,在Binder.java中
final class BinderProxy implements IBinder {
public native boolean pingBinder();
public native boolean isBinderAlive();
public IInterface queryLocalInterface(String descriptor) {
return null;
}
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
return transactNative(code, data, reply, flags);
}
...
}
名為checkParcel和傳輸肯定無(wú)關(guān),那么就是transactNative方法
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
它的實(shí)體仍然在android_util_Binder.cpp
// ----------------------------------------------------------------------------
static const JNINativeMethod gBinderProxyMethods[] = {
/* name, signature, funcPtr */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
};
找到android_os_BinderProxy_transact
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
...
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
...
status_t err = target->transact(code, *data, reply, flags);
...
return JNI_FALSE;
}
之前說(shuō)了env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get())它把BpBinder對(duì)象放進(jìn)了gBinderProxyOffsets.mObject,所以這里的target把gBinderProxyOffsets.mObject取出來(lái)相當(dāng)于拿到了BpBinder,所以這里調(diào)用了BpBinder的transact
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
也就是status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);分析該函數(shù)最終得到它會(huì)走向IPCThreadState::waitForResponse,這里是一個(gè)死循環(huán)
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
...
cmd = mIn.readInt32();
...
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
case BR_DEAD_REPLY:
err = DEAD_OBJECT;
goto finish;
case BR_FAILED_REPLY:
err = FAILED_TRANSACTION;
goto finish;
case BR_ACQUIRE_RESULT:
{
ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
const int32_t result = mIn.readInt32();
if (!acquireResult) continue;
*acquireResult = result ? NO_ERROR : INVALID_OPERATION;
}
goto finish;
case BR_REPLY:
...
goto finish;
default:
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
finish:
if (err != NO_ERROR) {
if (acquireResult) *acquireResult = err;
if (reply) reply->setError(err);
mLastError = err;
}
return err;
}
而此處cmd為BR_TRANSACTION,所以執(zhí)行的是default下的executeCommand,executeCommand中的代碼過(guò)多,這里我們只截取我們需要的,在這里會(huì)走到
if (tr.target.ptr) {
sp b((BBinder*)tr.cookie);
const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
if (error < NO_ERROR) reply.setError(error);
} else {
const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
if (error < NO_ERROR) reply.setError(error);
}
出現(xiàn)了我們的BBinder,根據(jù)前面的概念,這里就是服務(wù)端的東西了,我們繼續(xù)看服務(wù)端
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply, flags);
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
也就是onTransact(code, data, reply, flags);方法,由于JavaBBinder中重寫(xiě)了此方法,所以就會(huì)走到JavaBBinder中的onTransact方法,Java BBinder是android_util_Binder.cpp中的類(lèi),所以我們進(jìn)去看看virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
LOGV("onTransact() on %p calling object %p in env %p vm %pn", this, mObject, env, mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int strict_policy_before = thread_state->getStrictModePolicy();
thread_state->setLastTransactionBinderFlags(flags);
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, (int32_t)&data, (int32_t)reply, flags);
...
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
主要看我們的?jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,?code, (int32_t)&data, (int32_t)reply, flags)
很明顯了,用gBinderOffsets.mExecTransact來(lái)執(zhí)行了,而gBinderOffsets.mExecTransact是什么呢?
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
jclass clazz;
clazz = env->FindClass(kBinderPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gBinderOffsets.mExecTransact
= env->GetMethodID(clazz, "execTransact", "(IIII)Z");
assert(gBinderOffsets.mExecTransact);
gBinderOffsets.mObject
= env->GetFieldID(clazz, "mObject", "I");
assert(gBinderOffsets.mObject);
return AndroidRuntime::registerNativeMethods(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
很明顯了是我們java層的android/os/Binder類(lèi)中的execTransact方法,這樣我們又回到j(luò)ava層了,去看看
private boolean execTransact(int code, int dataObj, int replyObj,
int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// theoretically, we should call transact, which will call onTransact,
// but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly.
boolean res;
try {
res = onTransact(code, data, reply, flags);
} catch (RemoteException e) {
reply.writeException(e);
res = true;
} catch (RuntimeException e) {
reply.writeException(e);
res = true;
} catch (OutOfMemoryError e) {
RuntimeException re = new RuntimeException("Out of memory", e);
reply.writeException(re);
res = true;
}
reply.recycle();
data.recycle();
return res;
}
很明顯了調(diào)用了onTransact,由于ServiceManagerNative繼承于Binder并重寫(xiě)了onTransact方法,所以就會(huì)走到ServiceManagerNative中的onTransact,也就是我們繞世界一圈又回到了原點(diǎn)的感覺(jué)
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
{
try {
switch (code) {
case IServiceManager.GET_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = getService(name);
reply.writeStrongBinder(service);
return true;
}
...
...
}
} catch (RemoteException e) {
}
return false;
}
希望大家還沒(méi)有忘記我們的transact的內(nèi)容是GET_SERVICE_TRANSACTION,所以它會(huì)到getService,這并不是我們見(jiàn)過(guò)的getService,它位于/frameworks/base/libs/binder/IServiceManager.cppvirtual sp getService(const String16& name) const
{
unsigned n;
for (n = 0; n < 5; n++){
sp svc = checkService(name);
if (svc != NULL) return svc;
LOGI("Waiting for service %s...n", String8(name).string());
sleep(1);
}
return NULL;
}
checkService如下所示
virtual sp checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}
所以它事實(shí)上調(diào)用了一個(gè)遠(yuǎn)程的service并且傳遞了CHECK_SERVICE_TRANSACTION(其實(shí)就是常數(shù) 2),這個(gè)遠(yuǎn)程的service事實(shí)上在frameworks/base/cmds/servicemanager/service_manager.c中實(shí)現(xiàn)了,實(shí)際上我們已經(jīng)觸及到了最底層,而且它的onTransact如下所示
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
ptr = do_find_service(bs, s, len);
if (!ptr)
break;
bio_put_ref(reply, ptr);
return 0;
繼續(xù)找到do_find_service
void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)
{
struct svcinfo *si;
si = find_svc(s, len);
// ALOGI("check_service('%s') ptr = %pn", str8(s), si ? si->ptr : 0);
if (si && si->ptr) {
return si->ptr;
} else {
return 0;
}
然后找find_svc
struct svcinfo *find_svc(uint16_t *s16, unsigned len)
{
struct svcinfo *si;
for (si = svclist; si; si = si->next) {
if ((len == si->len) &&
!memcmp(s16, si->name, len * sizeof(uint16_t))) {
return si;
}
}
return 0;
}
此時(shí)已經(jīng)明了了,它從svclist這個(gè)鏈表中找到我們name("led")所對(duì)應(yīng)的service(LedService)并且返回。
至于我們?cè)鯓訉ervice插入這個(gè)鏈表的,想大家也能猜到了,我們之前注冊(cè)service的那幾步中調(diào)用的ServiceManager.addService的底層就是插入鏈表操作了,多少都離不開(kāi)我上面分析的這些過(guò)程,感興趣的朋友可以自己創(chuàng)建SourceInsight工程分析一下~
1.?紅茶一杯話Binder
2.?Android Binder 全解析
3.?簡(jiǎn)單說(shuō)Binder
4.?Deep Dive into Android IPC/Binder Framework
5.?Service與Android系統(tǒng)實(shí)現(xiàn)
6.?Binder那點(diǎn)事兒
7.?How does getSystemService() work exactly?