Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android binder 機制三(匿名Service)

android binder 機制三(匿名Service)

編輯:關於Android編程

什麼是匿名Service?凡是沒有到ServiceManager上注冊的Service,都是匿名Service。

還是拿上一篇的例子來舉例,看代碼:

status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
{
    status_t err = UNKNOWN_ERROR;
    const sp& service(getMediaPlayerService());
    if (service != 0) {
        sp 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 create(
        const sp& 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(reply.readStrongBinder());
}
直接跳到服務端MediaPlayerService,看create的真正實現:

sp MediaPlayerService::create(const sp& client,
        int audioSessionId)
{
    pid_t pid = IPCThreadState::self()->getCallingPid();
    int32_t connId = android_atomic_inc(&mNextConnId);

    sp 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 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 client =
                interface_cast(data.readStrongBinder());
            int audioSessionId = data.readInt32();
            sp 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. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved