各个类之间的关系图如下所示:
+----------+ |IInterface| +-----+----+ ^ | +-------+-------+ |IServiceManager| +-+-----------+-+ ^ ^ | | +----------------+--+ +-+------------------+ +--------------+ |ServiceManagerProxy| |ServiceManagerNative| <-has-+ServiceManager| ++------------------+ +-----------------+--+ +--------------+ | | (mRemote) | | | | +-------------+ +----------+ | +> | BinderProxy | | Binder | <-+ ++-----+------+ +--+-----+-+ | | | | | | | | (mObject) | +-------+ | (mObject) | +-----> |IBinder| <---+ | Java | +-------+ | +------------------------------------------------------+ C++ v v BpBinder BBinder
一次获取ServiceManager Proxy对象的调用过程如下图所示:
+-------------+ +-------------------+ +--------------+ |ServerManager| |ServerManagerNative| |BinderInternal| +------+------+ +---------+---------+ +-------+------+ | | | | | | | | | + getIServiceManager() | | | | +-----------------> | | getContextObject() | JNI +----------------------------------------------> | | | | +------------> | | | | | | | | | | <------------+ | | asInterface() | IBinder | | | <----------------------+ | | | | | new ServiceManagerProxy()| | | | <----------------------+ | | | | | | | | | | | | | | | | | + + +
Java Service牵涉到的类之间的关系和调用流程大致如下图所示:
+----------------------------------------------------+ | | | [Context Manager] | | ^ | +servicemanager-----------|--------------------------+ | +-----------------------+ | +----------------------------+ | +-----------------+ | | | | | | [Binder Client] | | | | +------------------------+ | | +-----------^-----+ | | | |IBinder | | | +------------|------+ | | | | +--------------------+ | | | |AIDL | | | | | | |Binder | | | | | +----------|----+ | | | | | | +----------------+ | | | | | |Proxy | | | | | | | | |AIDL | | | | | | | | | | | | | | | | +------------+ | | | | | | | +--------|--+ | | | | | | | | |Stub | | | | | | | | |IBinder | | | | | | | | | | | +--------+ | | | | | | | | | | | | | | | | | | | | | Binder | | | | | | | | | | +------v+ | | | | | | | | | | |Service | | | | | | | | | | | Token | | | | | | | | | | | +----^---+ | | | | | | | | | +----^--+ | | | | | | | | | +------|-----+ | | | | | | | +------|----+ | | | | | | | +--------|-------+ | | | | | +--------|------+ | | | | | +----------|---------+ | | | +----------|--------+ | | | +------------|-----------+ | +Process A---|----------+ | +Process B+----|-------------+ | | | +------------|------------v-----------------|--------+ | +---->[Binder Driver]<---------+ | | | +kernel----------------------------------------------+
通常来说,我们通过AIDL来定义service接口,系统会自动根据AIDL文件生成一个对应的java接口。
以IMyService为例,系统根据IMyService.aidl生成IMyService.java:
// IMyService.aidl interface IMyService { void hello(String val); } // IMyService.java /* * This file is auto-generated. DO NOT MODIFY. * Original file: C://Users//xinyu.he//workspace//LayoutTest//src//com//example//layouttest//IMyService.aidl */ package com.example.layouttest; public interface IMyService extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.example.layouttest.IMyService { private static final java.lang.String DESCRIPTOR = "com.example.layouttest.IMyService"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.example.layouttest.IMyService interface, * generating a proxy if needed. */ public static com.example.layouttest.IMyService asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.example.layouttest.IMyService))) { return ((com.example.layouttest.IMyService)iin); } return new com.example.layouttest.IMyService.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_hello: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); this.hello(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.example.layouttest.IMyService { 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 void hello(java.lang.String val) 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.writeString(val); mRemote.transact(Stub.TRANSACTION_hello, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_hello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } public void hello(java.lang.String val) throws android.os.RemoteException; }
可以看到系统自动生成了两个内部类IMyService.Stub和IMyService.Proxy。这两个类都实现了IMyService接口,其作用是对调用者屏蔽了Binder机制。
* IMyService.Stub用来描述一个自定义的Java服务。MyService继承于IMyService.Stub,并实现了hello()方法。
* IMyService.Stub.asInterface方法用来生成一个Proxy对象,Client获取到Proxy对象后,调用其hello()方法,Proxy对象向Service发送TRANSACTION_hello,触发Stub对象的onTransact方法。onTransact方法调用子类实现的hello()方法。
Java服务一般运行在Android系统进程或者应用程序进程中,需要在启动之前注册到Service Manager。由于android进程自带Binder线程池,所以只需将service注册到servicemanager中即可(不用初始化Binder等)。
注册service的代码一般如下所示:
ServiceManager.addService("MyService", new MyService());
service注册到ServerManager后,Android App便可以通过ServiceManager来获得service的一个proxy对象了。一般来说,获取一个service proxy对象的代码片段如下所示:
... myService = IMyService.Stub.asInterface(ServiceManager.getService("myService")); ...
该代码片段的内部逻辑如下所示:
+--------+ +----------+ +--------------+ +-------------------+ |Activity| |IMyService| |ServiceManager| |ServiceManagerProxy| +--------+ +-----+----+ +--------+-----+ +---------+---------+ | | | | | | getService(name)| | +----------------------------------------> | | | | getService(name) | | | +----------------------> | | | | GET_SERVICE_TRANSACTION | | | +------------------------> | | | | BinderProxy <----------------------------------------------------------------------------------------+ | | | | | | | | |Stub.asInterface(obj) | | +--------------------> | | | | | | | | | | | Stub.Proxy | | | <--------------------+ | | | | | | | | | | | | | | | | | |
使用service提供的服务时,直接在Proxy对象上调用AIDL定义好的接口方法即可。其内部逻辑如下所示: +--------+ +----------------------+ +--------------------+ +-------------+ +----------------------+ |Activity| |IMySer|ice(Stub.Proxy)| |mRemote(BinderProxy)| |Binder Driver| |MyService(Stub:Binder)| +---+----+ +---------+------------+ +-----------+--------+ +-----+-------+ +--------+-------------+ | | | | | | | | | | | mySer^ice.hello()| | | | +-----------------> | | | | | |transact(Stub.TRANSACTION_hello) | | | +--------------------------> | | | | | | | | | | | onTransact()...| | | | +----------------> | | | | | | execTransact() | | | | +------------------> | | | | | | | | | | onTransact() | | | | | +-------------+ | | | | | | | | | | +-----------> | | | | | | | | | | hello() | | | | | +-------------+ | | | | | | | | | | +-----------> | | | | | | | | | | |