关于servicemanager的设计:

还是这张结构图,由于ProcessState & IPCThreadState是与binder deriver交互的,

所以对于client端来说BpBinder以下的部分是透明的。

我们从Activity的getsystemservice来一步步分析整个servicemanager提供服务的过程。

在contextImple.java 中

        registerService(ALARM_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
}});

注册的代码是static block的形式。

    @Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}

getservice:

public Object getService(ContextImpl ctx) {
ArrayList<Object> cache = ctx.mServiceCache;
Object service;
synchronized (cache) {
if (cache.size() == 0) {
// Initialize the cache vector on first access.
// At this point sNextPerContextServiceCacheIndex
// is the number of potential services that are
// cached per-Context.
for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
cache.add(null);
}
} else {
service = cache.get(mContextCacheIndex);
if (service != null) {
return service;
}
}
service = createService(ctx);
cache.set(mContextCacheIndex, service);
return service;
}
}

所以可以看到最终调用就是注册函数的内容

IBinder b = ServiceManager.getService(ALARM_SERVICE);

ServiceManager.java:

    public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}

我们应用层看到的service对象是IBinder。

然后我们看看IServiceManager

    private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
} // Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
    /**
* Return the global "context object" of the system. This is usually
* an implementation of IServiceManager, which you can use to find
* other services.
*/
public static final native IBinder getContextObject();

getContextObject

可以看到注释说明,返回的就是全局唯一的ServiceManager对象。

class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
} public IBinder asBinder() {
return mRemote;
} public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}

AIDL的实现:

网上有很多关于AIDL的讨论,解释等等。

AIDL是什么?

Android Interface definition language:

所以aidl是google为了便利的实现binder机制,而创建的一种语言。

AIDL的目的是为了便于开发者可以快速书写创建进程间通信的一种语言,或者代码。

package com.htc.globalsearch.imagesearch.service.aidl;
import com.htc.globalsearch.imagesearch.service.aidl.PersonImageItem;
import com.htc.globalsearch.imagesearch.service.aidl.ICallBack; interface IBuildService{
int getServiceStatus();
int findPerson(String path,int filter);
void registerCallback(ICallBack cb);
void unregisterCallback(ICallBack cb);
}

看看生成后变成什么?

/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: D:\\AndroidDev\\github\\Example\\Examples\\ImageSearch\\src\\com\\htc\\globalsearch\\imagesearch\\service\\aidl\\IBuildService.aidl
*/
package com.htc.globalsearch.imagesearch.service.aidl;
public interface IBuildService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.htc.globalsearch.imagesearch.service.aidl.IBuildService
{
private static final java.lang.String DESCRIPTOR = "com.htc.globalsearch.imagesearch.service.aidl.IBuildService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.htc.globalsearch.imagesearch.service.aidl.IBuildService interface,
* generating a proxy if needed.
*/
public static com.htc.globalsearch.imagesearch.service.aidl.IBuildService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.htc.globalsearch.imagesearch.service.aidl.IBuildService))) {
return ((com.htc.globalsearch.imagesearch.service.aidl.IBuildService)iin);
}
return new com.htc.globalsearch.imagesearch.service.aidl.IBuildService.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getServiceStatus:
{
data.enforceInterface(DESCRIPTOR);
int _result = this.getServiceStatus();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_findPerson:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
int _arg1;
_arg1 = data.readInt();
int _result = this.findPerson(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_registerCallback:
{
data.enforceInterface(DESCRIPTOR);
com.htc.globalsearch.imagesearch.service.aidl.ICallBack _arg0;
_arg0 = com.htc.globalsearch.imagesearch.service.aidl.ICallBack.Stub.asInterface(data.readStrongBinder());
this.registerCallback(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_unregisterCallback:
{
data.enforceInterface(DESCRIPTOR);
com.htc.globalsearch.imagesearch.service.aidl.ICallBack _arg0;
_arg0 = com.htc.globalsearch.imagesearch.service.aidl.ICallBack.Stub.asInterface(data.readStrongBinder());
this.unregisterCallback(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.htc.globalsearch.imagesearch.service.aidl.IBuildService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public int getServiceStatus() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getServiceStatus, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public int findPerson(java.lang.String path, int filter) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(path);
_data.writeInt(filter);
mRemote.transact(Stub.TRANSACTION_findPerson, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public void registerCallback(com.htc.globalsearch.imagesearch.service.aidl.ICallBack cb) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((cb!=null))?(cb.asBinder()):(null)));
mRemote.transact(Stub.TRANSACTION_registerCallback, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@Override public void unregisterCallback(com.htc.globalsearch.imagesearch.service.aidl.ICallBack cb) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((cb!=null))?(cb.asBinder()):(null)));
mRemote.transact(Stub.TRANSACTION_unregisterCallback, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_getServiceStatus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_findPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_registerCallback = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_unregisterCallback = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
}
public int getServiceStatus() throws android.os.RemoteException;
public int findPerson(java.lang.String path, int filter) throws android.os.RemoteException;
public void registerCallback(com.htc.globalsearch.imagesearch.service.aidl.ICallBack cb) throws android.os.RemoteException;
public void unregisterCallback(com.htc.globalsearch.imagesearch.service.aidl.ICallBack cb) throws android.os.RemoteException;
}

IBuildService.java

public static abstract class Stub extends android.os.Binder implements com.htc.globalsearch.imagesearch.service.aidl.IBuildService

关键是这个class,stub继承自binder,而且实现了IbuildService的接口。

在看service

private class ImageSearchBuildServiceImpl extends IBuildService.Stub{

所以,service是实现了Stub的内容,进而可以实现这个方法。

而service的onbind就是返回这个stub

    @Override
public IBinder onBind(Intent intent) {
mCurrentCookie = intent.getLongExtra("cookie",-1);
Log.i(TAG, "[onBind] mCurrentCookie:"+mCurrentCookie);
iServiceImpl = new ImageSearchBuildServiceImpl(mImageSearchOperator);
return iServiceImpl;
}

通过bindservice,会把这个Ibinder对象返回给client端。

android 进程间通信---Service Manager(2)的更多相关文章

  1. android 进程间通信---Service Manager(1)

    Bind机制由4个部分组成.bind驱动,Client,ServiceManager &Service 1.Bind其实是一个基于linux系统的驱动,目的是为了实现内存共享. bind驱动的 ...

  2. Android 进程间通信——Service、Messenger

    概述 介绍绑定服务端的三种方式:同一进程绑定服务.跨进程绑定服务(Messenger).跨进程绑定服务(aidl). 重点说一下通过Messenger.Service实现的进程间通信. 详细 代码下载 ...

  3. Service Manager流程,派BC_REPLY,唤醒FregServer流程,返回BR_TRANSACTION_COMPLETE,睡眠等待proc-&gt;wait

    本文參考<Android系统源代码情景分析>,作者罗升阳 一.service manager代码:        -/Android/frameworks/base/cmd/service ...

  4. 浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6627260 在前面一篇文章浅谈Service ...

  5. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信 ...

  6. Android 核心分析 之六 IPC框架分析 Binder,Service,Service manager

    IPC框架分析 Binder,Service,Service manager 我首先从宏观的角度观察Binder,Service,Service Manager,并阐述各自的概念.从Linux的概念空 ...

  7. android 进程间通信---bind的前世

    在分析bind机制之前,我发现已经有一篇文章讲解的非常清晰,并且提出了很多问题. 地址:http://my.oschina.net/keeponmoving/blog/64218 一.Linux系统进 ...

  8. Android进程间通信(IPC)机制Binder简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6618363 在Android系统中,每一个应用 ...

  9. Android进程间通信(IPC)机制Binder简介和学习计划

    在Android系统,每个应用程序是由多个Activity和Service部件,这些Activity和Service有可能在相同的处理被执行,此外,还可以在不同的过程中进行. 然后.不是在同一个过程A ...

随机推荐

  1. JavaScript 的数据类型 相关知识点

    (1)基本数据类型介绍 JavaScript的数据类型分为两类:原始类型(primitive type)和对象类型(object type) 或者说是:可以拥有方法的类型和不能拥有方法的类型 或者说是 ...

  2. P6 EPPM Manual Installation Guide (Oracle Database)

    P6 EPPM Manual Installation Guide (Oracle Database) P6 EPPM Manual Installation Guide (Oracle Databa ...

  3. P6 EPPM Installation and Configuration Guide 16 R1 April 2016

    P6 EPPM Installation and Configuration Guide 16 R1         April 2016 Contents About Installing and ...

  4. C#设计模式——单件模式(Singleton Pattern)

    一.概述在软件开发过程中,我们有时候需要保证一个类仅有一个实例,比如在一个电脑用户下只能运行一个outlook实例.这时就需要用到单件模式.二.单件模式单件模式保证一个类仅有一个实例,并提供一个访问它 ...

  5. Chrome弹窗的简单应用(选择结构与循环结构)

    ★选择结构★ ★JS实现弹窗显示随机数 示例代码效果图   ★ 弹窗实现对随机数的进一步判断 示例代码效果图 ★综合应用   比较大小 ★ 判断成绩等级 ): : : : : alert(" ...

  6. ASP.NET的路由

    之前在探讨ASP.NET  MVC的路由时,无意发现原本ASP.NET也有路由机制的.在学习MVC的路由时觉得这部分的资料不太多,不怎么充实(也许是我不懂得去看微软的官方文档).后来也尝试一下ASP. ...

  7. Unity3D-terrain brush地形画刷无法出现在Scene中,无法刷地图2

    原因大概是 画刷brush 太小了,地图也太小了,没出出现. 如图,非正常状态: 解决方法: tag: terrain brush not working unity

  8. mysql启动不起来了!

    [root@iZ28r2sl9qkZ data]# service mysqld restartMySQL server PID file could not be found! [FAILED]St ...

  9. Java多线程--wait(),notify(),notifyAll()的用法

    忙等待没有对运行等待线程的 CPU 进行有效的利用(而且忙等待消耗cpu过于恐怖,请慎用),除非平均等待时间非常短.否则,让等待线程进入睡眠或者非运行状态更为明智,直到它接收到它等待的信号. Java ...

  10. jetty加载spring-context容器源码分析

    带着疑问开始 web.xml的顺序问题 先拿一个最简单的spring mvc web.xml来说问题,如下图:如果我将三者的顺序倒置或是乱置,会产生什么结果呢? 启动报错?还是加载未知结果?还是毫无影 ...