Android binder Mechanism 3 (anonymous Service), androidbinder
What is an anonymous Service? All services not registered on ServiceManager are anonymous services.
Let's take the previous example and look at the Code:
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;}
In BpMediaPlayerService, the create implementation is as follows:
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());}
Directly jump to the server MediaPlayerService to see the real implementation of 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;}
From the code, we can see that service-> create (this, mAudioSessionId) returns a BpMediaPlayer object of the Client type, where Client is the private internal class of MediaPlayerService, the statement is: class Client: publicBnMediaPlayer. In this way, the server and client of the Binder communication are established. The Client BpMediaPlayer is used by MediaPlayer, and the Server BnMediaPlayer is used by MediaPlayerService.
How does BpMediaPlayer obtain the handle value of BnMediaPlayer? When MediaPlayerService returns a reference to this binder, the binder driver saves various data of this binder object and creates a node. See the following code:
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;……}}
The answer is in this sentence: reply-> writeStrongBinder (player-> asBinder ());
When this reply is written to the Binder driver, the driver will specially process this IBinder type of data and create a handle for the Bbinder.
After the communication path is established, you can communicate: player-> setDataSource (fd, offset, length)
The subsequent implementation is the same as the general Service mentioned in the previous article.
How do Android JAVA statements understand binderService = (BindServiceLocalBinder) service) getService ();
Convert [service] to [BindService. LocalBinder] type, and call [getService ()] Method of [BindService. LocalBinder]
BinderService for Android programming
1. It must be returned. The Activity communicates with the Service through this. Otherwise, how do you call the methods in the Service?
2. normally, the onServiceDisconnected () method in ServiceConnection is not called, and its call time is when the Service is destroyed by an exception, for example, this method is automatically called only when memory resources are insufficient.
3. Certainly, an error will be reported. The bind mechanism means that if there is no bound object, the Service will be destroyed automatically. The Service has been unbound and may all be destroyed. How can we unbind it? You mean to add the judgment to the ServiceConnection object. onServiceDisconnected () is automatically called by the system and is definitely not executed. After the service is unbound, it cannot be used. Naturally, it cannot. First, you have figured out these mechanisms and carefully followed the logic.
If you want to add a value, add it to the Activity. In the listening event of the two buttons, change the Boolean value and the judgment according to the button (the Boolean value is declared in the Activity, and the global variable)