Android7.0 Binder通信(2) 服务进程的注册

前一篇博客中,我们分析了Binder通信的架构,以及其中作为服务管理者的ServiceManager的主要作用。
在这一篇博客中,我们主要来分析一下,一个普通的服务如何使用Binder通信,将自己注册到ServiceManager中。

我们选择从MediaServer进程入手,来分析整个服务注册过程。
之所以选择从这个进程开始分析,是因为在《深入理解Android 卷I》中,邓凡平前辈讲解过这个进程。对比前辈的分析和实际的代码,应该可以更快地完成知识的迭代。

在Android7.0中,MediaServer进程对应的代码定义于frameworks/av/media/mediaserver目录下。
mediaserver.rc中的定义如下:

service media /system/bin/mediaserver
    class main
    user media
    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
    ioprio rt 4
    writepid /dev/cpuset/foreground/tasks

从rc文件,可以看出mediaserver进程的class为main,因此它的启动时间应该在ServiceManager进程之后。当mediaserver进程被init进程加载后,将调用该进程对应的main函数。
main函数定义于main_mediaserver.cpp中:

int main()
{
    //看网上的资料,当服务器端关闭一个连接后,客户端仍不断向服务器发送数据时,系统将产生一个SIGPIPE信号给客户端进程,告知它不要再发送数据了
    //收到SIGPIPE信号后,默认行为是关闭进程;在这里忽略了SIGPIPE信号
    //mediaserver作为servicemanager的客户端,那么推测这里应该是针对servicemanager异常断开连接的处理
    signal(SIGPIPE, SIG_IGN);

    //获得ProcessState实例
    sp<ProcessState> proc(ProcessState::self());
    //获取与ServiceManager交互的代理对象
    sp<IServiceManager> sm = defaultServiceManager();
    .......................
    //注册服务
    MediaPlayerService::instantiate();
    ........................
    //创建线程池
    ProcessState::self()->startThreadPool();
    //加入线程池
    IPCThreadState::self()->joinThreadPool();
}

1 获取ProcessState
在main函数的开始,获取了ProcessState对象。每个进程只有一个ProcessState对象:

sp<ProcessState> ProcessState::self() {
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState;
    return gProcess;
}

从上面的代码可以看出,self通过单例的方式构造出ProcessState。
我们看看ProcessState的构造函数:

ProcessState::ProcessState()
    //open_driver将开启binder设备
    : mDriverFD(open_driver())
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
    //打开Binder驱动成功后
    if (mDriverFD >= 0) {
        //为Binder驱动分配地址接收数据,完成内核空间和用户空间地址的映射
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            ...........
            close(mDriverFD);
            mDriverFD = -1;
        }
    }
    ..............
}

我们看看open_driver函数:

static int open_driver() {
    //打开Binder设备
    int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
        //检查用户空间和内核空间版本是否一致
        .....
        //DEFAULT_MAX_BINDER_THREADS值为15
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        //设置该fd支持最大线程数为15
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        ................
    }
}

至此,ProcessState::self函数的主要流程就结束了。
从上面的代码我们知道:
进程通过创建ProcessState来打开Binder设备;
内核的Binder驱动会为进程分配对应的内存以接收数据;
每个进程最多同时为15个客户端提供服务。

2 调用defaultServiceManager得到ServiceManager的代理
在创建为ProcessState后,main函数调用了defaultServiceManager函数。
defaultServiceManager函数定义于IServiceManager.cpp中:

sp<IServiceManager> defaultServiceManager() 
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        //不断尝试获取IServiceManager
        while (gDefaultServiceManager == NULL) {
            //实际的创建
            gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                 sleep(1);
        }
    }

    return gDefaultServiceManager;
}

2.1 创建BpBinder
从上面的代码,可以看出defaultServiceManager是通过ProcessState::self()->getContextObject(NULL)来获取通信实体的。

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) {
    //注意此处的参数
    return getStrongProxyForHandle(0);
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) {
    sp<IBinder> result;

    AutoMutex _l(mLock);

    //ProcessState中维持了一个资源数组(实际为Vector): mHandleToObject, handle是获取具体资源的索引
    //lookupHandleLocked将按照索引查找对应的资源,如果没有发现对应的资源项,将创建一个新的资源项并返回
    //新创建的资源项的索引就是handle,并且内容处于待填充的状态
    handle_entry* e = lookupHandleLocked(handle);
    if (e != NULL) {
        IBinder* b = e->binder;
        //填充新创建的资源
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                //如果是创建与ServiceManager通信的对象,则先利用IPC通信向ServiceManager发送PING_TRANSACTION消息
                //通过返回值,判断ServiceManager是否正常存活;在ServiceManager的svcmgr_handler中,收到PING_TRANSACTION后,返回0
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                 if (status == DEAD_OBJECT)
                     retun NULL;
            }
            //利用handle创建一个BpBinder
            b = new BpBinder(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            .........
        }
    }
    //返回BpBinder
    return result;
}

在进一步分析之前,我们需要先需要了解一下BpBinder和BBinder。这里我们借鉴一下《深入理解Android 卷I》中的叙述:
Android中定义了BpBinder和BBinder,它们是Binder通信相关的代表,都是从IBinder类中派生而来。
BpBinder是客户端用来与Server交互的代理类;BBinder则代表了服务端。BpBinder与BBinder是一一对应的,即某个BpBinder只能与对应的BBinder交互。

在上文的代码中,MediaServer进程与ServerManager进程通信。
MediaServer进程是ServiceManager进程的客户端,因此在该Binder通信的连接中,MediaServer进程需要获取BpBinder对象。
从代码可以看出,Android使用handle来创建BpBinder,handle就是用来标识与该BpBinder通信的BBinder的。

2.2 构建出BpServiceManager
我们回到defaultServiceManager函数,在利用ProcessState创建出BpBinder后,代码可以转化为:

..........
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
..........

上述代码中,interface_cast为定义于IInterface.h中的模板:

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

因此上述代码可以被转化为:

gDefaultServiceManager = IServiceManager::asInterface(new BpBinder(0));

接下来我们需要看一下IServiceManager中定义的asInterface函数了。
先观察一下IServiceManager.h:

class IServiceManager : public IInterface
{
public:
    //IInterface中的宏定义
    DECLARE_META_INTERFACE(ServiceManager);
    //下面定义了服务接口
    ...............
}

IInterface中的宏定义如下:

#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const android::String16 descriptor;                          \
    static android::sp<I##INTERFACE> asInterface(                       \
            const android::sp<android::IBinder>& obj);                  \
    virtual const android::String16& getInterfaceDescriptor() const;    \
    I##INTERFACE();                                                     \
    virtual ~I##INTERFACE();      

根据宏定义,可以看IServiceManager中确实定义了接口:

static android::sp<IServiceManager> asInterface(const android::sp<android::IBinder>& obj);  

该函数的实现在IServiceManager.cpp中:

//BpServiceManager继承BpInterface<IServiceManager>,后者继承IServiceManager,负责实现业务接口
class BpServiceManager : public BpInterface<IServiceManager> {
    ..........
}

//IInterface中的宏定义
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

对应的宏定义如下:

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const android::String16 I##INTERFACE::descriptor(NAME);             \
    const android::String16&                                            \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
            const android::sp<android::IBinder>& obj)                   \
    {                                                                   \
        android::sp<I##INTERFACE> intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \

从上面的宏定义可以看出,最终defaultServiceManager中的代码可以被转化为:

gDefaultServiceManager = new BpServiceManger(new BpBinder(0));

上面已经提到,BpServiceManger定义于IServiceManger.cpp中,实现了IServiceManager.h定义的业务接口。
因此我们知道,调用defaultServiceManager的目的是:得到ServiceManager进程的服务代理对象。
该代理对象的接口与真实服务提供者的接口一样。

BpServiceManager作为服务代理对象,就是靠之前创建的BpBinder(0)来与实际的服务对象通信的,现在看看它的构造函数:

BpServiceManager(const sp<IBinder>& impl)
    : BpInterface<IServiceManager>(impl)
{
}

进一步追踪到BpInterface:

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase {
    ..........
}

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}

从上面的代码可以看出,BpBinder(0)最终传入了BpRefBase。

BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)
{
    ........
}

最终,BpRefBase中的mRemote对象持有了BpBinder(0)。
当用户调用BpServiceManager中的接口时,BpServiceManager利用mRemote对象将请求发往实际ServiceManager进程。

以上过程看起来比较混乱,我们来看看这部分流程涉及的对象之间的关系,大致上就能体会Android的设计初衷:


如上图所示,不同颜色的类代表了不同的设计意图。
注意实际的代码中,并不存在BnServiceManager和RealServiceManager这两个类,因为ServiceManager进程可以直接与Binder驱动通信,不需要依赖这一套继承体系。
这里只是将ServiceManger当做一个普通的服务提供进程,以便说明Android中一般情况下的Binder通信架构。

Tip1、图中绿色部分,为实际业务对应的类。IServiceManager中定义了服务应提供的实际接口,客户端进程中的BpServiceManger和服务端进程中的BnServiceManager均需要实现IServiceManager中定义的接口。RealServiceManager继承BnServiceManger,可以实现一些不依赖于Binder通信的方法。
Tip2、IInterface类实际上主要通过宏定义,起到转换的作用。
例如:其子类IServiceManager通过宏可以利用BpBinder构成BpServiceManager。
也就是说通过IInterface的继承体系,其子类可以利用BpBinder和BBinder构成满足实际业务要求的接口。
Tip3、BpInterface和BnInterface其实就是为了连接业务类和Binder类。不同的是BpInterface通过继承BpRefBase来持有一个BpBinder对象,而BnInterface是通过继承的方式来成为一个BBinder对象。
Tip4、RefBase的继承体系其实与Binder通信并没有实际的关联性,应该是用于管理对象引用的情况,与内存管理有关。
Tip5、BpBinder和BBinder继承自IBinder接口,实现与Binder驱动交互的接口。

通过上述的继承体系,我们可以看到Android将实际业务的继承体系,与Binder的继承体系分离开来。通过定义与业务相关的IServiceManger、BpServiceManger等类,以及IInterface体系提供的转换关系,就将实际业务的传输架构在Binder体系之上了。

3 注册服务
我们再次回到MediaServer的main函数,在调用defaultServiceManger获取到BpServiceManger对象后,MediaServer进程调用MediaPlayerService::instantiate(),将MediaPlayerService注册到ServiceManager中。

void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

我们看看BpServiceManager中的addService函数:

virtual status_t addService(const String16& name, const sp<IBinder>& service,
        bool allowIsolated)
{
    //将信息打包到data中,reply负责接受返回结果
    Parcel data, reply;
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);
    data.writeStrongBinder(service);
    data.writeInt32(allowIsolated ? 1 : 0);
    //remote实际为BpBinder
    status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    //判断返回结果是否OK
    return err == NO_ERROR ? reply.readExceptionCode() : err;
}

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;
}

从上面的代码可以看出,对于Binder通信来说,传输工作的实际操作者为IPCThreadState,因此我们需要进一步分析一下IPCThreadState。

3.1 IPCThreadState的构造

IPCThreadState* IPCThreadState::self()
{
    //初始时gHaveTLS为false
    if (gHaveTLS) {
restart:
        const pthread_key_t k = gTLS;
        //TLS是Thread Local Storage(线程本地存储空间)的简称
        //pthread_getspecific可以获取TLS中存储的数据
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) return st;
        //第一次时,下面创建出gTLS后,调用IPCThreadState的构造函数
        return new IPCThreadState;
    }

    if (gShutdown) {
        ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
        return NULL;
    }

    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {
        //第一次进入时,创建出存储IPCThreadState对象的key值gTLS
        int key_create_value = pthread_key_create(&gTLS, threadDestructor);
        if (key_create_value != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
                    strerror(key_create_value));
            return NULL;
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart;
}

现在看一下IPCThreadState的构造函数:

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),
      mMyThreadId(gettid()),
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
    //利用pthread_setspecific将自己存储到TLS中
    pthread_setspecific(gTLS, this);
    clearCaller();
    //mIn用来接收Binder设备的数据
    //mOut用来向Binder设备发送数据
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}

3.2 IPCThreadState的传输工作
创建出IPCThreadState后,将调用其transact函数进行实际的传输工作:

//注意handle为目的端句柄,在此流程中为0
//code为本次传输的消息码,即定义此次消息的目的,在此流程中为ADD_SERVICE_TRANSACTION
status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    //检查数据的有效性
    status_t err = data.errorCheck();
    ..........
    if (err == NO_ERROR) {
        //发送数据
        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
    }

    if (err != NO_ERROR) {
        if (reply) reply->setError(err);
        return (mLastError = err);
    }

    //flags默认为0
    if ((flags & TF_ONE_WAY) == 0) {
        ..................
        if (reply) {
            //等待结果
            err = waitForResponse(reply);
        } else {
            ...........
        }
        ................
    } else {
        ........
    }
    return err;
}

跟进writeTransactionData:

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
    binder_transaction_data tr;

    tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
    //handle传递给target,用以标识目的端,此处传递的值为0
    tr.target.handle = handle;
    tr.code = code;
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;

    //检查将传数据的正确性
    const status_t err = data.errorCheck();
    if (err == NO_ERROR) {
        //正常情况下,将数据填入到binder_transaction_data结构体中
        tr.data_size = data.ipcDataSize();
        tr.data.ptr.buffer = data.ipcData();
        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
        tr.data.ptr.offsets = data.ipcObjects();
    } else if (statusBuffer) {
        //这里是构造包含错误信息的结构体
        //在此流程中,statusBuffer为null
        ........
    } else {
        return (mLastError = err);
    }

    //注意此处只是将待发送数据写入到mOut缓冲中
    mOut.writeInt32(cmd);
    mOut.write(&tr, sizeof(tr));

    return NO_ERROR;
}

再看一下waitForResponse函数:

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    uint32_t cmd;
    int32_t err;

    while (1) {
        //talkWithDriver中,将进行实际的发送
        if ((err=talkWithDriver()) < NO_ERROR) break;

        //判断回复信息是否正确,是否需要处理
        err = mIn.errorCheck();
        if (err < NO_ERROR) break;
        if (mIn.dataAvail() == 0) continue;

        cmd = (uint32_t)mIn.readInt32();
        ............
        switch (cmd) {
        case BR_TRANSACTION_COMPLETE:
            if (!reply && !acquireResult) 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;
}

我们看看talkWithDriver函数:

//参数默认为true
status_t IPCThreadState::talkWithDriver(bool doReceive) 
{
    ..........
    //bwr为与binder设备交换数据的结构
    binder_write_read bwr;

    // Is the read buffer empty?
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();

    // We don't want to write anything if we are still reading
    // from data left in the input buffer and the caller
    // has requested to read the next data.
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;

    //将待发送的数据写入到bwr中
    //按上面的注释,当有数据要读取时,此次不写入数据
    bwr.write_size = outAvail;
    bwr.write_buffer = (uintptr_t)mOut.data();

    if (doReceive && needRead) {
        bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (uintptr_t)mIn.data();
    } else {
        bwr.read_size = 0;
        bwr.read_buffer = 0;
    }

    ................
    // Return immediately if there is nothing to do.
    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
    ...............
    do {
        ................
#if defined(__ANDROID__)
        //通过ioctl的方式与binder设备通信,读取数据到bwr中或将bwr中的数据写到binder设备中
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
#else
        err = INVALID_OPERATION;
#endif
        if (mProcess->mDriverFD <= 0) {
            err = -EBADF;
        }
        ...............
    } while (err == -EINTR);
    ....................
}

至此MediaServicePlayer的注册过程就结束了。结合之前博客分析ServiceManager的流程,我们知道svcmgr_handler收到消息后,会利用MediaServicePlayer对应信息构建出service info加入到svclist中。

4 startThreadPool和joinThreadPool
从前面的代码,我们看到MediaServer进程已经开启了Binder设备,同时将一些重要的服务注册到ServiceManager中。
在main函数的最后,MediaServer还调用了ProcessState::self()->startThreadPool和IPCThreadState::self()->joinThreadPool,我们现在看看这么做到底有什么用处。

4.1 startThreadPool

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        //创建了一个PoolThread,然后运行;此处参数为true
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

看看PoolThread类的定义:

class PoolThread : public Thread
{
public:
    PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    }

protected:
    virtual bool threadLoop()
    {
        //注意这里又调用了一次IPCThreadState::self()
        //由于IPCThreadState每个线程一个
        //因此MediaServer进程调用startThreadPool后,共有两个IPCThreadState;主线程和poolThread各有一个
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }

    const bool mIsMain;
};

4.2 joinThreadPool
注意在主线程和PoolThread中的IPCThreadState,均调用了joinThreadPool函数(默认参数就是true),且传入参数均为true。

void IPCThreadState::joinThreadPool(bool isMain)
{
    ...............
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
    ...............
    status_t result;
    do {
        //处理已经死亡的BBinder对象
        processPendingDerefs();
        //发送命令和读取请求
        result = getAndExecuteCommand();
        //根据result的结果,判断是否异常退出
        ..............
    } while (result != -ECONNREFUSED && result != -EBADF);
    ...............
    //异常退出循环
    mOut.writeInt32(BC_EXIT_LOOPER);
    talkWithDriver(false);
}

现在跟进getAndExecuteCommand:

status_t IPCThreadState::getAndExecuteCommand() 
{
    ........
    //前面已经提过,通过ioctl与binder设备通信,写入命令,读取请求
    result = talkWithDriver();
    if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        ..........
        cmd = mIn.readInt32();
        ..........
        //处理收到的消息
        result = executeCommand(cmd);
        ..........
    }
    return result;
}

现在我们明白了,MediaServer进程中,主线程和子线程的IPCThreadState调用joinThreadPool后,都会通过talkWithDriver向Binder设备发送消息,并接收和处理Binder设备返回的命令。

结束语
本篇博客以MediaServer进程为例,分析一个普通的服务进程如何使用Binder通信机制,包括开启Binder设备、向ServiceManager进程注册自己及利用IPCThreadState来与Binder设备通信。
其实Binder通信机制并不复杂,只是Android中将实际业务和Binder通信机制整合在了一起,看起来不太直观。了解整个继承结构和原理后,Binder通信就没有什么神秘的。


上图中左边为基于Binder通信的业务架构;右边为替换成socket的业务架构。容易看出Binder就是一种通信机制。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值