关于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. [Python] Basic operations in Pycharm

    From: http://learnpythonthehardway.org/book Comment with line comment: Ctrl + slash Run: Shift + F10 ...

  2. [git]查看某一行代码是谁写的

    git blame filename,'blame'意思为责怪!哈哈哈. 就会列出来每行的修改纪录.你可以通过行数或者代码来查看,是谁的锅!

  3. Android 学习笔记之使用多线程实现断点下载...

    PS:莫名其妙的迷茫... 学习内容: 1.使用多线程实现文件下载...   多线程下载是加快下载速度的一种方式..通过开启多个线程去执行一个任务..可以使任务的执行速度变快..多线程的任务下载时常都 ...

  4. .NET中Main函数使用小技巧

    摘要:任何语言开发出来的程序,都会有一个程序入口函数,可能每个语言所使用的程序入口函数名称不一样,但是它们的作用都是一样的,都是被操作系统去调用.那么本文主要总结.NET中的程序入口函数Main使用的 ...

  5. 分析SIX锁和锁分区导致的死锁

    什么是SIX锁? 官方文档锁模式中说到: 意向排他共享 (SIX):保护针对层次结构中某些(而并非所有)低层资源请求或获取的共享锁以及针对某些(而并非所有)低层资源请求或获取的意向排他锁. 顶级资源允 ...

  6. 【iOS】线程安全的文件读写

    前段时间看了一遍GCD(Grand Central Dispatch)多线程,GCD是苹果为多核开发提供的解决方案 多线程最常见的问题就是读写,比如数据库读写,文件读写,读取是共享的,写是互斥,允许多 ...

  7. web服务器之nginx与apache

    最近准备架设php的web服务器,以下内容可供参考. 1.nginx相对于apache的优点: 轻量级,同样起web 服务,比apache占用更少的内存及资源 抗并发,nginx 处理请求是异步非阻塞 ...

  8. ExtJs4 笔记(4) Ext.XTemplate 模板

    ExtJs4 笔记(4) Ext.XTemplate 模板 摘自:http://www.cnblogs.com/lipan/ 本篇将涉及到ExtJs中一个重要的概念,模板.话说Razor很神奇,但是我 ...

  9. Python记录-Pip安装

    1.第一步 下载py文件:https://bootstrap.pypa.io/ez_setup.py #!/usr/bin/env python """ Setuptoo ...

  10. SqlServer一张表数据导入另一张表,收藏使用,工作中更新数据错误很有用

    sql一张表数据导入另一张表   1.如果2张表的字段一致,并且希望插入全部数据,可以用这种方法:   INSERT INTO 目标表 SELECT * FROM 来源表;   2.比如要将 arti ...