編輯:關於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直接跳到服務端MediaPlayerService,看create的真正實現: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()); }
spMediaPlayerService::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); spclient = 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就一樣了。最近在網上看Moto 360的圖片,真是帥,帥了又帥,比帥更帥。所以想研究下Android wear。更新Android SDK,居然失敗了三次。1.第一次失敗出現Fai
Fragment是Android honeycomb 3.0
一般網絡數據通過http來get,post,那麼其中的數據不可能雜亂無章,比如我要post一段數據,肯定是要有一定的格式,協議的。常用的就是xml和json了。在此先要搭
翻譯工作耗時費神,如果你覺得本文翻譯得還OK,請點擊文末的“頂”;如有錯訛,敬請指正。謝謝。 Eclip