android binder 機制三(匿名Service)

來源:互聯網
上載者:User

標籤:android   binder   ipc   mediaplayer   通訊   

什麼是匿名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就一樣了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.