您的位置:首页 > 移动开发 > Android开发

IPC analysis on android with a demo (基于IPC实例分析android IPC机制)

2011-03-23 23:05 911 查看
IPC ANALYSIS ON ANDROID

TABLE OF CONTENTS
1 Overview... 3
1.1 Glossary.. 3
2 Binder file path.. 3
2.1 Binder driver part.. 3
2.2 Binder part.. 3
2.3 Servicemanager.. 3
3 Android IPC system... 4
3.1 Relation of classes. 4
3.2 Overall architecture.. 5
3.3 Android IPC system... 5
4 IPCdemo example.. 7
4.1 File architecture.. 7
4.2 Service Manager Run.. 7
4.3 Register MulService.. 9
4.4 Bp part.. 16
4.5 Bn part.. 21
4.6 Application.. 22
5 Summarize.. 23
6 References. 26

The communication between the Client side and the server side is through Binder. Binder comm-unication is implemented via binder driver of Linux. Binder communicating operation look like thread migration, IPC between two process look like A process come in B process and return back the result. Communication is synchronization not asynchronism.

1 Overview

This document will analysis the mechanism of IPC.You will understand the binder more and you can implement your IPC code by referencing to the example of IPCdemo.

The IPCdemo code that you can get from me,you can send email to me.


1.1 [b]Glossary[/b]

List all abbreviations and professional glossary which are understood difficulty here, and explain them in detailed. The table as follows:

Abbreviations and acronyms
Explanation
IPC
Inter-Process Communication
Binder
The base of Android Inter-Process Communication


2 [b]Binder file path[/b]


2.1 [b]Binder driver part[/b]

kernel/ include/linux/binder.h
kernel/drivers/android/binder.c


2.2 [b]Binder part[/b]

frameworks/base/cmds/servicemanager/binder.h
frameworks/base/cmds/servicemanager/binder.c
frameworks/base/cmds/servicemanager/service_manager.c


2.3 [b]Servicemanager[/b]

frameworks/base/include/utils/IInterface.h
frameworks/base/include/utils/Binder.h
frameworks/base/include/utils/BpBinder.h
frameworks/base/include/utils/IBinder
frameworks/base/include/utils/Parcel.h
frameworks/base/include/utils/IPCThreadState.h
frameworks/base/include/utils/ProcessState.h
frameworks/base/libs/utils/Binder.cpp
frameworks/base/libs/utils/BpBinder.cpp
frameworks/base/libs/utils/IInterface.cpp
frameworks/base/libs/utils/IPCThreadState.cpp
frameworks/base/libs/utils/Parcel.cpp
frameworks/base/libs/utils/ProcessState.cpp


3 [b]Android IPC system[/b]


3.1 [b]Relation of classes[/b]

The relation of classes in Binder is show in the figure 3-2



figure 3-1 relation of classes in Binder

RefBase.h :
reference count, define RefBase class.
Parcel.h :
define container for transfered data in IPC, define Parcelclass
IBinder.h
Abstract interface of Binder object, define IBinder class.
Binder.h
Base function of Binder object, define Binder and BpRefBase class.
BpBinder.h
function of BpBinder, define BpBinder class
IInterface.h
define common class for abstract go through interface of Binder. Define IIterface class, class template BnInterface, class template BpInterface.
ProcessState.h
the class represent state of process, define ProcessState class.
IPCThreadState.h
this represent the state of thread, define IPCThreadState class.


3.2 [b]Overall architecture[/b]

The overall architecture of Android IPC system is shown in the picture.



Figure 3-2 overall architecture of Android IPC system

Binder Driver
It’s the core of IPC system. It transfers data between service provider and service user.
Service provider
It provides some kind of service. It will parser the received RPC call data from binder driver and do the real action.
Service_manager
It’s a special service provider. It provides service manager service for other service provider.
Service user
It remote calls service provider. It will generate an RPC call data and send it to binder driver.


3.3 [b]Android IPC system[/b]

Native part(Bn):
Implement BnABC:: BnTransact()
Register service:IServiceManager::AddService
Proxy(Bp):
Implement some function,transfer BpABC::remote()->transact()
Client: Get ABC interface, then transfer interface,(transfer BpABC in fact,then transfer BnABC via IPC, at last transfer the detail function)
Both BnABC and BpABC inherite interface ABC.
The main function of BpABC is communicate, it does not execute detail function; BnABC is a interface class, it needs a detail class to inherite and implement.
Communicate in BpABC and BnABC via IPC.

Next,let me show how the Android IPC system works



Figure 3-3 Android IPC system


4 [b]IPCdemo example[/b]


4.1 [b]File architecture[/b]



Figure 4-1
JAVA: IPCdemo
Jni: native.cpp
MulProvider: MulProvider.h, MulProvider.cpp
IMul: IMul.h, IMul.cpp
Mul: Mul.h, Mul.cpp
MulService: MulService.cpp

4.2 Service Manager Run

service_manager provide service manager service to other process. It must be started before any other service gets running.
Service_manager.h
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024);
if (binder_become_context_manager(bs)) {           //是该进程成为服务管理进程
LOGE("cannot become context manager (%s)/n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);                       /*函数调用1*/
return 0;
}


It first open “/dev/binder” driver and then call BINDER_SET_CONTEXT_MGR ioctl to let binder kernel driver know it acts as a manager. Then it enters into a loop to wait for any data from other process.

Binder.c    /*函数调用1*/      /

void binder_loop(struct binder_state *bs, binder_handler func)
{
int res;
struct binder_write_read bwr;
unsigned readbuf[32];
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;
readbuf[0] = BC_ENTER_LOOPER;
binder_write(bs, readbuf, sizeof(unsigned));
for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (unsigned) readbuf;
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
LOGE("binder_loop: ioctl failed (%s)/n", strerror(errno));
break;
}
res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
if (res == 0) {
LOGE("binder_loop: unexpected reply?!/n");
break;
}
if (res < 0) {
LOGE("binder_loop: io error %d %s/n", res, strerror(errno));
break;
}
}
}

Pay attention to BINDER_SERVICE_MANAGER.
Binder.h
/* the one magic object */
#define BINDER_SERVICE_MANAGER ((void*) 0)

BINDER_SERVICE_MANAGER is the registered handle for service_manager. The other process must use this handle to talk with service_manager.


4.3 [b]Register MulService[/b]

MulService.cpp

int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
/*创建了一个新的统一的服务接口类,一个进程中想调用其他进程的服务一般的都先创建一个统一的服务接口类 ,然后调用这个服务接口类中的getService  获得自己想要的另一个进程中的服务*/
sp<IServiceManager> sm = defaultServiceManager();                   /*函数调用2*/
LOGI("ServiceManager: %p", sm.get());
LOGV("register MulService!");
Mul::instantiate();                                                   /*函数调用3*/
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}

To get an IServiceManager instance the only method is to call defaultServiceManager implemented in IServiceManager.cpp.
IServiceManager.cpp            /*函数调用2*/

sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));                          /*函数调用4*/
}
}
return gDefaultServiceManager;
}

gDefaultServiceManager is defined in libutil, so any program or library which included libutil will have this symbol, it’s unique in one process. The first time gDefaultServiceManager is NULL, so it will first get a ProcessState instance through ProcessState::self().One process has only one ProcessState instance. ProcessState will open “/dev/binder” driver for IPCThreadState use.

ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
if (gProcess != NULL) return gProcess;

AutoMutex _l(gProcessMutex);
if (gProcess == NULL) gProcess = new ProcessState;
return gProcess;
}

ProcessState.cpp

ProcessState::ProcessState()
/*这一步打开  /dev/binder驱动,并验证了下binder的版本及协议是否匹配  */
: mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {

#if !defined(HAVE_WIN32_IPC)
/*MMAP映射/dev/binder 驱动文件到虚拟内存mVMStart */
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
// *sigh*
LOGE("Using /dev/binder failed: unable to mmap transaction memory./n");
close(mDriverFD);
mDriverFD = -1;
}
#else
mDriverFD = -1;
#endif
}
if (mDriverFD < 0) {
// Need to run without the driver, starting our own thread pool.
}
}

Now we have an instance of ProcessState, let’s look at the getContextObject.
ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
if (supportsProcesses()) {
/* 创建了一个  BpBinder 类,并隐式转化为sp<IBinder>  ,因为IBinder 是BBinder的父类*/
return getStrongProxyForHandle(0);                                /*函数调用5*/
} else {
return getContextObject(String16("default"), caller);
}
}

The board support binder driver, so we will get into getStrongProxyForHandle. (Handle 0 is reserved for service manager, which will be explained later.)
ProcessState.cpp                 /*函数调用5*/

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one.  See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}


The first time b will be NULL, so the code will new an BpBinder instance. BpBinder is a base proxy class for remote binder object.
BpBinder.cpp
BpBinder::BpBinder(int32_t handle)
: mHandle(handle)
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
{
LOGV("Creating BpBinder %p handle %d/n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
IPCThreadState::self()->incWeakHandle(handle);                      /*函数调用6*/
}

IPCThreadState::incWeakHandle will add a BC_INCREFS command in output buffer.

IPCThreadState.cpp               /*函数调用6*/
void IPCThreadState::incWeakHandle(int32_t handle)
{
LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)/n", handle);
mOut.writeInt32(BC_INCREFS);
mOut.writeInt32(handle);
}

Now getContextObject returns a BpBinder instance, it will be interface_cast to IServiceManager. interface_cast is defined in IInterface.h.
IInterface.h                /*函数调用4*/
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}


The code will be extended like this.

inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);                /*函数调用7*/
}


Now let’s take a look at definition of IServiceManager.
IServiceManager.h

class IServiceManager : public IInterface
{
public:
DECLARE_META_INTERFACE(ServiceManager);
virtual sp<IBinder>         getService( const String16& name) const = 0;
virtual sp<IBinder>         checkService( const String16& name) const = 0;
virtual status_t                addService( const String16& name,
const sp<IBinder>& service) = 0;
virtual Vector<String16>    listServices() = 0;
enum {
GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,
LIST_SERVICES_TRANSACTION,
};
};


IInterface.h               /*函数调用7*/

/*下面定义了两个宏 DECLARE_META_INTERFACE  和IMPLEMENT_META_INTERFACE   前一个宏申明了函数asInterface 和getInterfaceDescriptor ,后一个宏定义了它们    */
#define DECLARE_META_INTERFACE(INTERFACE)
static const String16 descriptor;
static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);
virtual const String16& getInterfaceDescriptor() const;
I##INTERFACE();
virtual ~I##INTERFACE();
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
const String16 I##INTERFACE::descriptor(NAME);                      /* 这一句NAME赋给descriptor */
const String16& I##INTERFACE::getInterfaceDescriptor() const {
return I##INTERFACE::descriptor;
}
sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)
{
sp<I##INTERFACE> intr;
if (obj != NULL) {
intr = static_cast<I##INTERFACE*>(
obj->queryLocalInterface(
I##INTERFACE::descriptor).get());
if (intr == NULL) {
intr = new Bp##INTERFACE(obj);       }               /*第一次调用时候会 new 一个Bp##INTERFACE  */
}                                                         /*类型为I##INTERFACE */
return intr;
}
I##INTERFACE::I##INTERFACE() { }
I##INTERFACE::~I##INTERFACE() { }

这里调用IServiceManager.cpp 中的BpServiceManager的构造函数来创建类对象


DECLARE_META_INTERFACE macro is defined as follows in IInterface.h. And it will be extended to the following code:

static const String16 descriptor;
static sp<IServiceManager> asInterface(const sp<IBinder>& obj);
virtual String16 getInterfaceDescriptor() const;


As you can see,DECLARE_META_INTERFACE macro declares two functions which are implement-ted by IMPLEMENT_META_INTERFACE macro in IServiceManager.cpp.
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
The code will be extended like this.

/*函数调用7*/
const String16 IServiceManager::descriptor(NAME);
String16 IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
sp<IServiceManager> IServiceManager::asInterface(const sp<IBinder>& obj)
{
sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj);
}
}
return intr;
}


So IServiceManager::asInterface will finally new a BpServiceManager instance and return it to user. BpServiceManager works as a proxy for remote BnServiceManager. Any operation on IServiceManager now actually is to call the corresponding virtual functions in BpServiceManager.

Mul::instantiate()
Mul.h                      /*函数调用3*/
static int instantiate() {
LOGE("AddService instantiate");
int r = defaultServiceManager()->addService(
String16("MULSERVICE"), new Mul());
LOGE("AddService r = %d/n", r);
return r;
}

首先defaultServiceManager() 是sp<IServiceManager> 而在IServiceManager 类定义中addService 成员函数只是虚函数声明了一下没有被定义,只有在BpServiceManager(继承IServiceManager) 类中才定义了addService函数,如下:
ServiceManager.cpp

status_t BServiceManager::addService(const String16& name, const sp<IBinder>& service)
{
AutoMutex _l(mLock);
LOGI("ServiceManager: addService(%s, %p)/n", String8(name).string(), service.get());
const ssize_t res = mServices.add(name, service);
if (res >= NO_ERROR) {
mChanged.broadcast();
return NO_ERROR;
}
return res;
}

mServices is defined inServiceManager.h
ServiceManager.h
KeyedVector<String16, sp<IBinder> > mServices;


4.4 Bp part

MulProvider.h
MulProvider(){
sm  = defaultServiceManager();
binder=sm->getService(String16("MULSERVICE"));        /*函数调用8*/
itf=interface_cast<IMul>(binder);
}


在MulProvider中我们可以看到MulProvider通过defaultServiceManager,即通过刚才的BpServiceManager得到我们在ServiceManager中注册的MULSERVICE服务.
IServiceManager.cpp               /*函数调用8*/

binder = sm->getService(String16("media.camera"));
sm 是sp<IServiceManager> 而在IServiceManager  类定义中getService 成员函数只是虚函数声明了一下没有被定义,只有在BpServiceManager(继承IServiceManager) 类中才定义了getService函数,如下:
virtual sp<IBinder> getService(const String16& name) const
{
unsigned n;
for (n = 0; n < 5; n++){
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
LOGI("Waiting for sevice %s.../n", String8(name).string());
sleep(1);
}
return NULL;
}
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
/* remote()  是BpRefBase 类中的函数 ,BpServiceManager 是继承BpRefBase  的发送  data 中的数据并将结果
回写到reply中  */
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}


binder=sm->getService(String16("MULSERVICE"))函数调用返回sp<IBinder>,然后通过itf=interface_cast <IMul>(binder),得到MULSERVICE的Bpmul,过程和刚才的/*函数调用4*/得到BpServiceManager一样,这里不再具体分析。

IMul.h

class IMul : public IInterface
{
public:
DECLARE_META_INTERFACE(Mul);
virtual int       mul(int a,int b){return 1;};
virtual String16  getCall(){ String16* a=new String16("1");return *a; };
enum {
MUL_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
GETCALL_TRANSACTION
};
};
class BnMul : public BnInterface<IMul>
{
public:
virtual status_t    onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};


在IMul.h,我们定义了IMul类,该类继承自IInterface,还有BnMul类,该类继承自BnInterface。

IMul.cpp
class BpMul : public BpInterface<IMul>
{
public:
BpMul(const sp<IBinder>& impl)
: BpInterface<IMul>(impl)
{
}
virtual int mul(int a,int b)
{
/*  数据容器类,要发送的数据和接收的数据都存放在这个里面*/
Parcel data, reply;
/* 把服务的名字写入容器类data */
data.writeInterfaceToken(IMul::getInterfaceDescriptor());
data.writeInt32(a);
data.writeInt32(b);
/*在很多地方我们都可以看到remote()->transact  传输实际上是调用Bpbinder的成员函数:transact 我现在的分析的代码都是在Proxy代理(Bp)这一块 ,后面我们会分析到 Native 本地 (Bn) 这一块,先提一下Bn 那一块会以onTransact 函数来解析BpMul ::MUL_TRANSACTION对应的命令!下面会详细说明*/
status_t err = remote()->transact(MUL_TRANSACTION, data, &reply); /*函数调用9*/
return reply.readInt32();
}
virtual String16 getCall()
{
Parcel data, reply;
data.writeInterfaceToken(IMul::getInterfaceDescriptor());
status_t err = remote()->transact( MUL_TRANSACTION, data, &reply);
return reply.readString16();
}
};


/*函数调用9*/
remote()->transact(MUL_TRANSACTION, data, &reply);
remote()是BpRefBase 类的成员函数。 remote(); 实际调用Binder.h 中的
inline IBinder* remote() { return mRemote; }
remote()->transact(MUL_TRANSACTION, data, &reply)调用IBinder的成员函数transact,实际是调用BpBinder.cpp中的transact
如下:
BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}

这个函数主要调用了IPCThreadState::self()->transact ,IPCThreadState::self 也使用自己的成员函数创建了一个类对象, 分析下IPCThreadState::self()->transact
IPCThreadState.cpp

status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
flags |= TF_ACCEPT_FDS;
if (err == NO_ERROR) {
/*这里将数据写入容器内*/
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}

if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
/*这步发送和接收返回结果存入reply 容器*/
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
}
return err;
}

IPCThreadState.cpp

status_t IPCThreadState::talkWithDriver(bool doReceive)
{

#if defined(HAVE_ANDROID_OS)
/*最终完成与驱动的交互*/
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
}


4.5 [b]Bn part[/b]

IMul.cpp
status_t BnMul::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case MUL_TRANSACTION: {
CHECK_INTERFACE(IMul, data, reply);
int a = data.readInt32();
int b = data.readInt32();
int c = mul(a,b);
reply->writeInt32(c);
return NO_ERROR;
} break;
case GETCALL_TRANSACTION: {
CHECK_INTERFACE(IMul, data, reply);
String16 c=getCall();
reply->writeString16(c);
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}


BnMul以onTransact函数来解析BpMul 传过来对应的命令
Mul.cpp
Mul::Mul()
{
}
int Mul::mul(int a,int b)
{
return a*b;
}
String16 Mul::getCall()
{
String16 *t=new String16("Mul Service Call");
return *t;
}

Mul.cpp中的类Mul继承自BnMul,在该类中实现了具体的函数mul和getCall。


4.6 [b]Application[/b]

在Eclipse中建立android2.2工程,代码如下:
ipcdemo.java
package smrdn.ipcdemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class ipcdemo extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
int sum = Native.mul(181, 94);
tv.setText("181 * 94 = " + Integer.toString(sum));
setContentView(tv);
}
}
class Native {
static {
// The runtime will add "lib" on the front and ".o" on the end of
// the name supplied to loadLibrary.
System.loadLibrary("jnimul");
}
static native int mul(int a, int b);
}


然后将程序下载到手机中,在adb shell 中启动mulservice,然后我们可以看到如下的效果




5 [b]Summarize[/b]

图5-1是IPC机制的流程图,图5-2是IPC调用的时序图,如果大家需要更加深入的了解IPC,可以阅读Binder的驱动程序部分。



图5-1 IPC机制流程图



图5-2 IPC调用时序图
我们得出:
如果一个服务需要通过binder机制对外提供跨进程的接口,需要做下面这些事情:
(1) 第一步,需要为这个接口定义一个继承自IInterface的接口类,假设叫做IMyService。
(2) 第二步,需要定义两个binder类,其中一个是代理类BpMyService,需继承自BpInterface;另一个是实现类BnMyService,需继承自BnInterface。
(3) 第三步,定义BnMyService的子类,这个子类可以是任何名字,比如就叫MyService,在其中真正实现接口所提供的各个函数。
(4) 第四步,创建MyService的实例,注册到服务管理器(如IMediaPlayerService),也可以在其它接口的函数中创建。


6 [b]References[/b]

一篇android的IPC机制binder实例AudioFlinger国外文档 http://blog.chinaunix.net/u1/38994/showart_1676822.html Android JAVA Binder IPC System http://blog.chinaunix.net/u1/38994/showart_1680617.html binder官网 http://blog.chinaunix.net/u1/38994/showart_1222450.html Android IPC 通讯机制源码分析 http://hi.baidu.com/albertchen521/blog/item/30c32d3f4bee993a71cf6ca0.html http://hi.baidu.com/albertchen521/blog/item/822058d0f63ea2d4562c84a1.html
Reference/android/app/Service
Android底层库libutils介绍 http://www.androidin.com/learn/cn/200901/22-437.html Android 初学
http://www.fulema.com/forumdisplay.php?fid=4

大家会发现IServiceManager类和父类IInterface 找不到asInterface这个成员函数,这个函数实际上是通过上面的DECLARE_META_INTERFACE(ServiceManager); 这条语句来申明的,并且在IServiceManager.cpp 中使用IMPLEMENT_META_INTERFACE(Mul, "android.smrdn.IMul"); 定义了它们。

备注:整理于2010.12.07, 本篇博客百度文库: http://wenku.baidu.com/view/e9eb7c1efad6195f312ba61a.html
Email:safransx@gmail.com QQ: 1104472716
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: