www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]轉(zhuǎn)載請注明出處:http://blog.csdn.net/callon_h/article/details/52073268 引子 上一篇博客從內(nèi)核驅(qū)動到android app講述了android通過

轉(zhuǎn)載請注明出處:http://blog.csdn.net/callon_h/article/details/52073268

引子

上一篇博客從內(nèi)核驅(qū)動到android app講述了android通過框架層訪問到硬件的方法。

這一篇博客,承接上一篇,來講述其訪問硬件的第二種方法中涉及的binder的知識(其實不止是硬件服務(wù),后面大家會看到)。

有人看過上一篇博客源碼的可能問,從上篇給的源碼中完全沒有看到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;
}
看到這里有的朋友可能想起來了,這是我們之前用ILedService.aidl自動生成的ILedService.java,路徑其實上一篇說過了,只是代碼沒貼。

那么其中最重要的Stub類它繼承(extends)于Binder并且還實現(xiàn)(implements)了android.os.ILedService里的接口。
這里就引出了我們的主角Binder,它是android源碼分析中的重中之重。


Binder的概念 文章1-揭示本質(zhì):

簡單地說,Binder是Android平臺上的一種跨進程交互技術(shù)。

從實現(xiàn)的角度來說,Binder核心被實現(xiàn)成一個Linux驅(qū)動程序,并運行于內(nèi)核態(tài)。這樣它才能具有強大的跨進程訪問能力。


文章2-溯其根源:

在Linux系統(tǒng)里面,進程之間是相互隔離的,也就是說進程之間的各個數(shù)據(jù)是互相獨立,互不影響,而如果一個進程崩潰了,也不會影響到另一個進程。這樣的前提下將互相不影響的系統(tǒng)功能分拆到不同的進程里面去,有助于提升系統(tǒng)的穩(wěn)定性,畢竟我們都不想自己的應(yīng)用進程崩潰會導(dǎo)致整個手機系統(tǒng)的崩潰。而Android是基于Linux系統(tǒng)進行開發(fā)的,也充分利用的進程隔離這一特性。

這些Android的系統(tǒng)進程,從System Server 到 SurfaceFlinger,各個進程各司其職,支撐起整個Android系統(tǒng)。而我們進行的Android開發(fā)也是和這些系統(tǒng)進程打交道,通過他們提供的服務(wù),架構(gòu)起我們的App程序。那么有了這些進程之后,問題緊接著而來,我們怎么和這些進程合作了?答案就是IPC。

Linux System 在IPC中,做了很多工作,提供了不少進程間通信的方式,下面羅列了幾種比較常見的方式。

Signals 信號量Pipes 管道Socket 套接字Message Queue 消息隊列Shared Memory 共享內(nèi)存按照復(fù)用的角度上看,既然有這么多”輪子”后,就應(yīng)該合理利用這些”輪子”,從而方便地調(diào)用系統(tǒng)服務(wù)。然而事實并沒有這么簡單,Android系統(tǒng)作為嵌入式的移動操作系統(tǒng),通信條件相對更加苛責(zé)一些,苛責(zé)的地方提現(xiàn)在:
拮據(jù)的內(nèi)存,移動設(shè)備上的內(nèi)存情況不同于PC平臺,內(nèi)存受限,因而需要有合適的機制來保證對空閑進程的回收Android 不支持System V IPCs安全性問題顯得更為突出,移動平臺特有的權(quán)限問題需要Death Notification(進程終止的通知)的支持

由于前面提及的特殊性,先前的輪子已經(jīng)不能滿足所有的需求了,因而Android上就有了 Binder。 Binder 是一個基于OpenBinder開發(fā),Google在其中進行了相應(yīng)的改造和優(yōu)化,在面向?qū)ο笙到y(tǒng)里面的IPC/組件,適配了相關(guān)特性,并致力于建立具有擴展性、穩(wěn)定、靈活的系統(tǒng)。

但盡管如此,跨進程調(diào)用還是受到了 Linux 進程隔離的限制,而解決方案就是將其置于所有進程都能共享的區(qū)域 –Kernel,而 Binder Driver 提供的功能也就是讓各進程使用內(nèi)核空間,將進程中的地址和Kernel中的地址映射起來,其中Linux ioctl 函數(shù)實現(xiàn)了從用戶空間轉(zhuǎn)移到內(nèi)核空間的功能。在 Binder Driver 的支持下,就能實現(xiàn)跨進程調(diào)用。


Binder的架構(gòu) 文章3-述其本質(zhì)

Binder架構(gòu)包括服務(wù)器接口、Binder驅(qū)動、客戶端接口三個模塊。

Binder服務(wù)端(Server):一個Binder服務(wù)端實際上就是Binder類的對象,該對象一旦創(chuàng)建,內(nèi)部則會啟動一個隱藏線程,會接收Binder驅(qū)動發(fā)送的消息,收到消息后,會執(zhí)行Binder對象中的onTransact()函數(shù),并按照該函數(shù)的參數(shù)執(zhí)行不同的服務(wù)器端代碼。onTransact函數(shù)的參數(shù)是客戶端調(diào)用transact函數(shù)的輸入。

Binder驅(qū)動(Driver):任意一個服務(wù)端Binder對象被創(chuàng)建時,同時會在Binder驅(qū)動中創(chuàng)建一個mRemote對象,該對象也是一個Binder類。客戶端訪問遠程服務(wù)端都是通過該mRemote對象。

客戶端(Client):獲取遠程服務(wù)在Binder驅(qū)動中對應(yīng)的mRemote引用,然后調(diào)用它的transact方法即可向服務(wù)端發(fā)送消息。

作為架構(gòu)先了解到這,然后我們先來通過上一篇的Led的例子來理解架構(gòu)。


細說Led中的Binder: AIDL中的Binder架構(gòu):


首先附上詳細的ILedService.java程序并加以說明:

/*
 * 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;
}
只要細心一點一定能找到客戶端Client需要的class Proxy還有服務(wù)端Server需要的class Stub,其實它們都在這一個文件中。

而為什么我能說客戶端需要的是Proxy而不是Stub?或者說為什么服務(wù)端需要的是Stub而不是Proxy?

原因1. 我們先把注意力集中到Proxy類中的

@Override public int LedOpen() throws android.os.RemoteException

這個方法上(其實LedOn和LedOff也是一樣的),它調(diào)用了一句:

mRemote.transact(Stub.TRANSACTION_LedOpen, _data, _reply, 0);
接下來我們看Stub類的

@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);
}
細節(jié)我們可以不深究但是至少我們能夠得到這樣一個結(jié)論:我們的Proxy類transact了一個TRANSACTION_LedOpen“消息”,而Stub類中的onTransact可以來通過switch響應(yīng)這個“消息”,并且調(diào)用我們真正在LedService.java上實現(xiàn)的

public int LedOpen() throws android.os.RemoteException;
方法。

原因2. 我們來看LedService這個類到底是繼承自誰?

public class LedService extends ILedService.Stub

原因3. ?Proxy意為代理人,Stub意為票根。

總結(jié)一下(1圖取自文章4,2圖取自文章5),個人覺得用圖的方式總結(jié)是最好的:


該圖中的Proxy為之前所述的ILedService.Stub.Proxy,Stub為ILedService.Stub,Client你可以認為是調(diào)用

 iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));  
的app,而Service則可以認為是LedService。


而上圖是我們正常的service訪問流程圖,正常的service一般都含有IBinder mBinder對象和OnBind()方法,而在app的activity端有onServiceConnection()對應(yīng)之,其中g(shù)etPid()對應(yīng)于我們的LedOpen()等AIDL定義的接口方法。這些都只是框架,如果要到代碼層分析還需要了解一些Binder中的概念。


文章1—深入Binder概念

BpBinder——Binder中的代理方對應(yīng)類,C++語言描述,繼承自IBinder

BBinder——Binder中響應(yīng)方對應(yīng)類,C++語言描述,繼承自IBinder

BpInterface——進程并不直接和BpBinder(Binder代理)打交道,而是通過調(diào)用BpInterface(接口代理)的成員函數(shù)來完成遠程調(diào)用的

BnInterface——BnInterface是繼承于BBinder的,它并沒有采用聚合的方式來包含一個BBinder對象

ProcessState——在每個進程中,會有一個全局的ProcessState對象,ProcessState的字面意思就是“進程狀態(tài)”,當(dāng)然應(yīng)該是每個進程一個ProcessState


Led代碼層的Binder

我們通過前一篇博文可以看到,要完成LedService還需要的重要一步是注冊進ServiceManager

led = new LedService();  
ServiceManager.addService("led", led);

由ServiceManager統(tǒng)一管理,而client進程與這些Service通信時,首先需要向ServiceManagerService中查找相應(yīng)的Service,拿到返回值后再將返回值轉(zhuǎn)成對應(yīng)的接口,就可與對應(yīng)的Service進行通信了,也就是我們在app中使用的語句

 iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));  
這里會涉及到一個問題:ServiceManagerService本身就是一個單獨的進程,客戶端必須先跨進程與ServiceManagerService交互之后才可與自己需要的Service進行交互。解決的辦法為:將ServiceManagerService的handle(每一個Service的唯一標(biāo)識)設(shè)置為0,這樣就可以拿到SMS在本進程中的代理對象了(c層中直接new的一個BpBinder(0)對象,這拿到的就是SMS的代理對象)。但對于別的Service而言,不能采用該種方法,因為它們的句柄由SMS控制,不一定是固定的。

ServiceManagerService類似于DNS服務(wù)器,每一臺pc都會向dns服務(wù)器中查詢自己無法解析的域名對應(yīng)的ip地址,然后使用拿到的ip地址進行訪問。而client首先向ServiceManagerService查詢自己需要的Service的handle(相當(dāng)于ip),然后才跟對應(yīng)的Service通信。而

ServiceManager.getService("led")
就相當(dāng)于從dns查詢ip的過程,我們首先分析它:

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會在緩存中找我們name對應(yīng)的service,找不到就調(diào)用getIServiceManager()拿到我們的ServiceManager Service,然后通過getService拿到我們的IBinder對象

再往下分析,首先看getIServiceManager()實際上調(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的子類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是一個native方法,它拿到的是一個整個系統(tǒng)的context object,并且經(jīng)常是IServiceManager的實現(xiàn)類,通過它你可以找到其他的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對象具體是什么

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;
}
在這里我們就會發(fā)現(xiàn),其實我們得到是BpBinder,所以ProcessState::self()->getContextObject(NULL)其實就是BpBinder(0)

這里的參數(shù)為什么是0呢?之前我也提到了,0指的就是我們ServiceManager的binder對象,這個是唯一的,所以javaObjectForIBinder(env, b)也就是javaObjectForIBinder(env,BpBinder(0)),接著我們不再貼長代碼分析,沒有意義,得出結(jié)論比較重要:

1. 分析javaObjectForIBinder,它返回的是jobject javaObjectForIBinder(JNIEnv* env, const sp& val),一個jobject對象,并且這個jobject對象主要是從gBinderProxyOffsets強制轉(zhuǎn)化而來的,并且env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());它把BpBinder對象放進了gBinderProxyOffsets.mObject

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其實就是android/os/BinderProxy我們的java類,也就是我們上面返回的是一個BinderProxy,BinderProxy是什么呢,一會我們會講到,也就是說BinderInternal.getContextObject()我們最終得到是BinderProxy,也就是我們ServiceManager中的ServiceManagerNative.asInterface(BinderInternal.getContextObject());其實就是ServiceManagerNative.asInterface(BinderProxy);也就是getIServiceManager().getService(name);其實就是ServiceManagerNative.asInterface(BinderProxy).getService(name)。所以我們就又回到ServiceManagerProxy類中的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其實就是BinderProxy類,所以它的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和傳輸肯定無關(guān),那么就是transactNative方法

public native boolean transactNative(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;
它的實體仍然在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;
}
之前說了env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get())它把BpBinder對象放進了gBinderProxyOffsets.mObject,所以這里的target把gBinderProxyOffsets.mObject取出來相當(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ù)最終得到它會走向IPCThreadState::waitForResponse,這里是一個死循環(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中的代碼過多,這里我們只截取我們需要的,在這里會走到

            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中重寫了此方法,所以就會走到JavaBBinder中的onTransact方法,Java BBinder是android_util_Binder.cpp中的類,所以我們進去看看
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來執(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類中的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并重寫了onTransact方法,所以就會走到ServiceManagerNative中的onTransact,也就是我們繞世界一圈又回到了原點的感覺

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;
    }
希望大家還沒有忘記我們的transact的內(nèi)容是GET_SERVICE_TRANSACTION,所以它會到getService,這并不是我們見過的getService,它位于/frameworks/base/libs/binder/IServiceManager.cpp
virtual 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();

    }
所以它事實上調(diào)用了一個遠程的service并且傳遞了CHECK_SERVICE_TRANSACTION(其實就是常數(shù) 2),這個遠程的service事實上在frameworks/base/cmds/servicemanager/service_manager.c中實現(xiàn)了,實際上我們已經(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;

}
此時已經(jīng)明了了,它從svclist這個鏈表中找到我們name("led")所對應(yīng)的service(LedService)并且返回。

至于我們怎樣將service插入這個鏈表的,想大家也能猜到了,我們之前注冊service的那幾步中調(diào)用的ServiceManager.addService的底層就是插入鏈表操作了,多少都離不開我上面分析的這些過程,感興趣的朋友可以自己創(chuàng)建SourceInsight工程分析一下~


參考文章:

1.?紅茶一杯話Binder

2.?Android Binder 全解析

3.?簡單說Binder

4.?Deep Dive into Android IPC/Binder Framework

5.?Service與Android系統(tǒng)實現(xiàn)

6.?Binder那點事兒

7.?How does getSystemService() work exactly?

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉