关于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端。