关于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();
可以看到注释说明,返回的就是全局唯一的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; }
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端。