Binder 框架 -- binder 用户空间框架

Binder 框架 – binder 用户空间框架

Binder框架 – android AIDL 的使用

Binder框架 – 用户空间和驱动的交互

Binder框架 – Binder 驱动

Binder 框架 – binder 用户空间框架

一 ServiceManager 启动

int main(int argc, char **argv)
{
    struct binder_state *bs;

    bs = binder_open(128*1024);
    if (!bs) {
        ALOGE("failed to open binder driver\n");
        return -1;
    }

    if (binder_become_context_manager(bs)) {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }

    ......

    binder_loop(bs, svcmgr_handler);

    return 0;
}

1. 打开binder 设备

bs = binder_open(128*1024); 打开binder 设备驱动。相关的信息保存在binder_state 结构中。

struct binder_state
{
     int fd;                binder 设备的fd
     void *mapped;          映射到用户空间的地址
     size_t mapsize;        大小 
};

struct binder_state *binder_open(size_t mapsize)
{
    struct binder_state *bs;
    struct binder_version vers;

    bs = malloc(sizeof(*bs));
    if (!bs) {
        errno = ENOMEM;
        return NULL;
    }

    bs->fd = open("/dev/binder", O_RDWR | O_CLOEXEC);


    if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
        (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
        ......
    }

    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);


    return bs;
}

binder_open 中做的工作主要是打开binder 设备,然后通过mmap 将binder内核空间映射到用户空间。标准的linux 设备访问方法:

  1. open(“/dev/binder”, O_RDWR | O_CLOEXEC); 打开设备
  2. ioctl(bs->fd, BINDER_VERSION, &vers) ioctl 命令设置版本号。 在下面对binder 驱动的访问中主要是通过 ioctl 函数,没有用我们常见的 read write, 这个也是binder 驱动设计的一个特点
  3. mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); 内核空间mapsize大小映射到用户空间,注意映射的空间是只读权限。
  4. 设备的文件描述符, 用户空间地址, 大小用binder_state结构体保存。

2. binder_become_context_manager 通知binder驱动成为管理者。

int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

注意最后一个参数为0;函数设计上可能是为了表示ServiceManager hander为0.但是在驱动中收到的消息为BINDER_SET_CONTEXT_MGR,已经表示是表示ServiceManager自己,直接把自己的 hander置为0,没有使用这个参数。ServiceManager 本身管理服务的特殊性,没有其它进程负责它的注册,ServiceManager需要自己完成注册,同时自己的handler 为0.

3. binder_loop 进入循环

binder_loop调用的时候同时传入回调函数。

  1. binder_write(bs, readbuf, sizeof(uint32_t)); 调用 ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 通知binder 驱动进入循环。这次调用没有阻塞。
  2. 在 for 循环中的 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 阻塞,当有消息来得时候,读出数据,交给binder_parse解析同时指定svcmgr_handler func处理解析数据。
void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    uint32_t readbuf[32];

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;

    readbuf[0] =  ;
    binder_write(bs, readbuf, sizeof(uint32_t));

    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;

        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }

        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
        if (res == 0) {
            ALOGE("binder_loop: unexpected reply?!\n");
            break;
        }
        if (res < 0) {
            ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
            break;
        }
    }
}

4. svcmgr_handler 处理信息

svcmgr_handler func 函数指针指向svcmgr_handler
信息主要有这几个类型:

  • SVC_MGR_GET_SERVICE 获取服务
  • SVC_MGR_CHECK_SERVICE 检查服务
  • SVC_MGR_ADD_SERVICE 添加服务,如mediaservice 添加就会到这里
  • SVC_MGR_LIST_SERVICES 主要是 service list 命令使用
int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    struct svcinfo *si;
    uint16_t *s;
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
    int allow_isolated;

    if (txn->target.ptr != BINDER_SERVICE_MANAGER)
        return -1;

    if (txn->code == PING_TRANSACTION)
        return 0;
    ......

    switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
        if (!handle)
            break;
        bio_put_ref(reply, handle);
        return 0;

    case SVC_MGR_ADD_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, handle, txn->sender_euid,
            allow_isolated, txn->sender_pid))
            return -1;
        break;

    case SVC_MGR_LIST_SERVICES: {
        uint32_t n = bio_get_uint32(msg);

        if (!svc_can_list(txn->sender_pid)) {
            ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
                    txn->sender_euid);
            return -1;
        }
        si = svclist;
        while ((n-- > 0) && si)
            si = si->next;
        if (si) {
            bio_put_string16(reply, si->name);
            return 0;
        }
        return -1;
    }
    default:
        ALOGE("unknown code %d\n", txn->code);
        return -1;
    }

    bio_put_uint32(reply, 0);
    return 0;
}

5 servicemanager 是一单线程,

可能因为是工作不太繁忙,不需要多线程加班。
ps -t | grep servicemanager
system 2450 1761 10228 752 ffffffff f7685976 S /system/bin/servicemanager

servicemanager 已经启动,并且在一个while 循环中阻塞,等待唤醒。

ProcessState

ProcessState 是单例模式,每个进程只有一个实例。ProcessState在构造函数中会打开binder 驱动获取文件描述符mDriverFD,设置binder的参数,为进程进行binder 通信准备必要的条件。

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

ProcessState::ProcessState()
    : mDriverFD(open_driver())
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
     if (mDriverFD >= 0) {
         mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
    }
 }

static int open_driver()
{
    int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
        int vers = 0;
        status_t result = ioctl(fd, BINDER_VERSION, &vers);

        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        }
    } else {

    }
    return fd;
}

open_driver 函数和binder_open 差不多,打开设备驱动,设置版本号并检查, 然后设置BINDER_SET_MAX_THREADS ,支持的最大线程数。

  1. open(“/dev/binder”, O_RDWR | O_CLOEXEC);
  2. octl(fd, BINDER_VERSION, &vers);
  3. ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
  4. 最后在构造函数中mmap。 为什么不在 open_driver 中一起把这个事情给做了呢?从API调用的角度放在一起比较合适吧。

startThreadPool 函数

从名字上看启动一个线程池,创建一个新的线程,spawnPooledThread isMain 参数为true,new了一个PoolThread,然后run函数 启动threadLoop(),在threadLoop 调用 IPCThreadState::self()->joinThreadPool(mIsMain); 对线程调用的封装,具体可以参考线程使用的方法。

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());
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

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

protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }

    const bool mIsMain;
};

IPCThreadState

IPCThreadState 是一个线程单例模式

IPCThreadState 是一个看似单例却不是单例的类。主要涉及了线程的局部存储,看下self 的实现:
第一次进来 gHaveTLS == false 所以走下边的代码:

  1. if (pthread_key_create(&gTLS, threadDestructor) != 0)
    创建线程的局部存储然后goto 到 restart;
  2. 调用pthread_getspecific,由于线程的局部key k还没有关联变量这是返回值为空;所以
    new IPCThreadState;看到这里很疑惑,创建了线程的局部存储key 却没有变量存储到线程的局部存储里面,直接new 了一个IPCThreadState,和self 函数名也不匹配,搞什么鬼呢。
  3. 继续看IPCThreadState的构造函数:这下明白了 在构造函数里面IPCThreadState把自己作为线程的局部存储
    pthread_setspecific(gTLS, this);
  4. 如果是第二次进来 gHaveTLS == true.直接pthread_getspecific 获取IPCThreadState自身。

IPCThreadState 是一个线程单例模式, 持有两个类型为Parcel 的变量

class IPCThreadState{

            ......        
private:
       Parcel              mIn;
       Parcel              mOut;
}

IPCThreadState* IPCThreadState::self()
{
    if (gHaveTLS) {
restart:
        const pthread_key_t k = gTLS;
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) return st;
        return new IPCThreadState;
    }

    if (gShutdown) return NULL;

    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {
        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            return NULL;
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart;
}

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),
      mMyThreadId(gettid()),
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
    pthread_setspecific(gTLS, this);
    clearCaller();
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}

IPCThreadState::joinThreadPool

在上面的ProcessState::startThreadPool() 中调用了IPCThreadState::joinThreadPool 那这个函数到底干了什么呢。

  1. 首先根据是否主线程 mOut.writeInt32,注意参数为BC_ENTER_LOOPER 或者BC_REGISTER_LOOPER 这个后边分析。
  2. 在一个循环中不停的getAndExecuteCommand。
  3. 在getAndExecuteCommand 首先talkWithDriver, 然后executeCommand,和ServiceManager 类似,在一个循环中不停的读取binder 驱动,然后解析数据。

到这里其实服务端和客户端的交互框架已经建立。在后边的MediaPlayerService中看下具体的细节。

void IPCThreadState::joinThreadPool(bool isMain)
{   
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

    status_t result;
    do {
        ......
        result = getAndExecuteCommand();
        ......
    } while (result != -ECONNREFUSED && result != -EBADF);

    ......
}

status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;

    result = talkWithDriver();
     if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();

        result = executeCommand(cmd);
        ......
        }
    }

    return result;
}

Binder 通信架构

Android 为了便于使用Binder 通信,提供了一套框架,只要继承这个框架的各个类,就能够实现一个Binder通信服务。主要分为代理端和服务端。代理端和服务端通的通信通过 IInterface BpInterface BnInterface IBinder BpBinder BBinder 这几个模板类进行。

binder 下的相关类类图:
binder 对象图

MediaPlayerService 启动

ServiceManager 单独运行在一个进程中,其它的Android系统服务如MediaPlayerService 如何启动和注册呢,在ServiceManager 的启动过程中分析到有一个 SVC_MGR_ADD_SERVICE 处理流程,在while 循环中已经阻塞。在上面分析IPCThreadState::joinThreadPool 的时候也会在循环中阻塞,根据linux 进程间通信的知识,双方应该互相发送数据唤醒对方。在这里就是MediaPlayerService 进程和ServiceManager 相互交互了,MediaPlayerService 对它的Client 来说是一个服务端,但是对ServiceManager 来说是一个客户端。
MediaPlayerService 同样基于上面的Binder通信框架,继承了相关的子类。
看一下MediaPlayerService 的启动代码。

int main(int argc __unused, char** argv)
{
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();

        ALOGI("ServiceManager: %p", sm.get());
        AudioFlinger::instantiate();
        MediaPlayerService::instantiate();
        ResourceManagerService::instantiate();
        CameraService::instantiate();
        AudioPolicyService::instantiate();
        SoundTriggerHwService::instantiate();
        RadioService::instantiate();
        registerExtensions();

        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
}

defaultServiceManager

调用 sp sm = defaultServiceManager()获取ServiceManger 的代理; 函数定义在IServiceManager.cpp 中

sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) 
        return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}
ProcessState::getStrongProxyForHandle
  1. 依次调用ProcessState 的 getContextObject ->
  2. getStrongProxyForHandle 函数,参数为0,
    首先查表 lookupHandleLocked。注意BpBinder.mHander = 0;

ProcessState 为单例模式,持有一个 VectormHandleToObject对象,进程中所有的Binder 对象都会添加到这个容器中。由于是是第一次查找,mHandleToObject为空,lookupHandleLocked会添加一个未初始化过的handle_entry对象,所以e->binder == NULL。

struct handle_entry {
    IBinder* binder;
    RefBase::weakref_type* refs;
};

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = NULL;
        e.refs = NULL;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return NULL;
    }
    return &mHandleToObject.editItemAt(handle);
}

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

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

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {

                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }

            b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

e->binder == NULL handle == 0 条件成立,经过下面两步调用

status_t status = IPCThreadState::self()->transact(0, IBinder::PING_TRANSACTION, data, NULL, 0);
b = new BpBinder(handle); 

变成了

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

其中ServiceManager 的hander 为0,
transact 函数第一个参数为0,表示的是传递给 handle 为0 的Service,就是ServiceManager,

interface_cast 以及DECLARE_META_INTERFACE IMPLEMENT_META_INTERFACE

interface_cast 以及DECLARE_META_INTERFACE IMPLEMENT_META_INTERFACE 这几个宏定义在
IInterface.h 中。

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

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();                                            \


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() { }                                   \

替换掉INTERFACE 变成了, 这段代码变成了:

android::sp<IServiceManager> interface_cast<IServiceManager>(const sp<IBinder>& obj){
    return IServiceManager::asInterface(obj);
}
android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)
{
     android::sp<IServiceManager> intr;                                 
     if (obj != NULL) {                                              
         intr = static_cast<IServiceManager>(obj->queryLocalInterface(IServiceManager::descriptor).get());               
         if (intr == NULL) {                                         
                intr = new BpServiceManager(obj);                          
          }                                                           
      }                                                               
      return intr; 
}

BpBinder(0)->queryLocalInterface, queryLocalInterface 为IBinder 的虚函数,默认返回空值,BpBinder 继承IBinder,并且没有覆盖queryLocalInterface。所以sp sm = defaultServiceManager()实际是这个样子:

sp<IServiceManager> sm = new BpServiceManager(obj);

这段代码就是为了拿到ServiceManager的BpServiceManager. 当中在线程中做了记录,然后对引用计数做了处理,通过transact 通知了ServiceManager 。这样我们就拿到了ServiceManger 的客户端BpServiceManager。代码好绕,有没有看到其他的代码使用这个机制?

MediaPlayerService 注册到 ServiceManger

再回到MediaPlayerService 初始化的代码:

int main(int argc __unused, char** argv)
{
        ......

        AudioFlinger::instantiate();
        MediaPlayerService::instantiate();
        。。。。。。

        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
}

MediaPlayerService::instantiate

调用 MediaPlayerService::instantiate();

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

defaultServiceManager() 返回的结果就是BpServiceManager,所以这段代码变成了:

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

BpServiceManager()->addService

 virtual status_t addService(const String16& name, const sp<IBinder>& service,
            bool allowIsolated)
{
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
}

在 remote 就是在new BpServiceManager 中穿进去的BpBinder(0)。

BpBinder 的 transact

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

IPCThreadState transact 先后调用了writeTransactionData 和 waitForResponse, writeTransactionData中把binder 相关的通信数据写入binder 驱动。然后呢,然后呢,其实在一开始ServiceManger 已经在binder_loop 中阻塞了,现在写入binder 驱动数据,binder_loop会被激活,读出数据 解析,然后ServiceManger 向bindr 驱动注册Service,将结果写入reply 参数。waitForResponse 读取reply 结果。通信完成,MediaPlayService 注册完成。

启动线程池

在最后先后调用了,根据上面的分析,startThreadPool 最后也调用了joinThreadPool。也就是启动了两个线程。

        ProcessState::self()->startThreadPool(); //启动子线程
        IPCThreadState::self()->joinThreadPool(); //主线程循环

在LoopThread 反复调用 joinThreadPool 函数做如下工作:

 result = talkWithDriver();
     if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();

        result = executeCommand(cmd);
        ......
        }
    }

有一个疑问,为什么需要两个线程

总结:

  1. ProcessState.self() 建立实例
  2. defaultServiceManager()
  3. ProcessState::self()->getContextObject(nuLl)->ProcessState::self()->getStrongProxyForHandle(0)-> New BpBinder(0)
  4. interface_cast(BpBinder(0))->asInterface(BpBinder(0)) -> new BpServiceManager(BpBinder(0));
  5. 依次调用 BpServiceManger::addService ->BpBinder::transact->IPCThreadState::self()->transact 通知服务端
  6. IPCThreadState::waitForResponse 等待服务端返回。
  7. 启动线程池

调用序列图:

mediaservice 序列图

binder 调用过程图

为什么需要两个线程,在需要用到回调函数的Binder通信中,在BnClass::doSome 是有callback ,而此时BpClass 进程中只有一个线程,这个线程正在waitRespose,而无法响应callback , 就会造成异常。

参考Binder 调用异常

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值