什么是匿名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就建立起来了。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. Spark基本工作流程及YARN cluster模式原理(读书笔记)
  2. Labview调用Python脚本
  3. mybatis实战教程(mybatis in action)之五:与spring3集成
  4. 转mysql 多表 update sql语句总结
  5. 压力测试 webbench
  6. input的onkeyup效果 超级简短代码
  7. JAVA中取子字符串的几种方式
  8. solrcloud使用中遇到的问题及解决方式
  9. SQL_NO_CACHE
  10. ab做压力测试
  11. IntelliJ IDEA 使用随笔
  12. Flask中endpoint的理解
  13. WSDL中文版——详解
  14. Ajax练习题
  15. java 线程 捕获异常
  16. 洛谷 P2073 送花【Treap】题解+AC代码
  17. CodeBlocks(17.12) 代码调试基础方法&amp;快捷方式
  18. 利用微信支付的订单查询接口可以在APP 中提高支付的可靠性
  19. Sublime Text 执行后只有运行时间,没有执行结果!解决方法!
  20. WordPress &lt;= 4.6 命令执行漏洞(PHPMailer)复现分析

热门文章

  1. HDU 2476 区间DP String painter
  2. centos 装 android studio
  3. linux 安装SNV服务
  4. Linux cp复制
  5. SQL处理XML
  6. 怎么创建SpringBoot项目
  7. POJ 2155 Matrix【二维线段树】
  8. 【kmp+求所有公共前后缀长度】poj 2752 Seek the Name, Seek the Fame
  9. leetcode 349 map
  10. hdu4035 Maze (树上dp求期望)