什么是匿名Service?凡是没有到ServiceManager上注册的Service,都是匿名Service。

还是拿上一篇的例子来举例,看代码:

status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length){    status_t err = UNKNOWN_ERROR;    const sp<IMediaPlayerService>& service(getMediaPlayerService());    if (service != 0) {        sp<IMediaPlayer> player(service->create(this, mAudioSessionId));        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||            (NO_ERROR != player->setDataSource(fd, offset, length))) {            player.clear();        }        err = attachNewPlayer(player);    }    return err;}

在BpMediaPlayerService中,create的实现如下:

virtual sp<IMediaPlayer> create(        const sp<IMediaPlayerClient>& client, int audioSessionId) {    Parcel data, reply;    data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());    data.writeStrongBinder(client->asBinder());    data.writeInt32(audioSessionId);    remote()->transact(CREATE, data, &reply);    return interface_cast<IMediaPlayer>(reply.readStrongBinder());}
直接跳到服务端MediaPlayerService,看create的真正实现:

sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,        int audioSessionId){    pid_t pid = IPCThreadState::self()->getCallingPid();    int32_t connId = android_atomic_inc(&mNextConnId);    sp<Client> c = new Client(            this, pid, connId, client, audioSessionId,            IPCThreadState::self()->getCallingUid());    ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,         IPCThreadState::self()->getCallingUid());    /* add by Gary. start {{----------------------------------- */    c->setScreen(mScreen);    /* add by Gary. end   -----------------------------------}} */    c->setSubGate(mGlobalSubGate);  // 2012-03-12, add the global interfaces to control the subtitle gate    wp<Client> w = c;    {        Mutex::Autolock lock(mLock);        mClients.add(w);    }    return c;}

从代码中,我们可以看出,service->create(this, mAudioSessionId)是返回了一个参数为Client类型的BpMediaPlayer对象,其中Client为MediaPlayerService的私有内部类,其声明为:class Client : publicBnMediaPlayer。这样,Binder通信的服务端和客户端就建立起来了。Client端BpMediaPlayer由MediaPlayer使用,Server端BnMediaPlayer由MediaPlayerService使用。

BpMediaPlayer是如何获得BnMediaPlayer的handle值的呢?答案在MediaPlayerService返回这个binder的引用的时候,binder驱动保存了这个binder实体的各种数据,创建了节点,看下面的代码:

status_t BnMediaPlayerService::onTransact(    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    switch (code) {        case CREATE: {            CHECK_INTERFACE(IMediaPlayerService, data, reply);            sp<IMediaPlayerClient> client =                interface_cast<IMediaPlayerClient>(data.readStrongBinder());            int audioSessionId = data.readInt32();            sp<IMediaPlayer> player = create(client, audioSessionId);            reply->writeStrongBinder(player->asBinder());            return NO_ERROR;        } break;……}}

答案就在这句话中:reply->writeStrongBinder(player->asBinder());

当这个reply写到Binder驱动时,驱动会特殊处理这种IBinder类型的数据,为Bbinder建立一个handle。

通信的通路建立后,就可以进行通信了:player->setDataSource(fd, offset, length)

之后的实现,和上一篇讲的普通Service就一样了。

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. Android(安卓)打开相册选择单张图片实现代码
  3. Android(安卓)使用junit测试
  4. Android(安卓)studio 多渠道打包
  5. android基本程序单元Activity
  6. Android中TextView滚动显示信息的效果
  7. Android无需申请权限拨打电话的两种方式
  8. android的TabActivity
  9. android jni调用opencv库失败 could not load library libopencv

随机推荐

  1. Android(安卓)Error:Execution failed fo
  2. Android(安卓)Studio连接STF失效
  3. android获取textview的行数
  4. Android(安卓)AES加密算法及事实上现
  5. Android禁止EditText自动弹出软键盘的方
  6. Android各类资源收集(持续更新中...)
  7. Android应用程序请求SurfaceFlinger服务
  8. 带着问题学习 Android(安卓)Handler 消息
  9. android弹出对话框
  10. Android下Bonjour服务的使用