转载

android 进程间通信---Service Manager(2)

关于servicemanager的设计:

android 进程间通信---Service Manager(2)

还是这张结构图,由于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; } 
android 进程间通信---Service Manager(2)
/**      * 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);   }

看看生成后变成什么?

android 进程间通信---Service Manager(2)
/*  * 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端。

正文到此结束
Loading...