当前位置: 代码迷 >> Android >> android 进程间通信-Service Manager(二)
  详细解决方案

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

热度:68   发布时间:2016-04-27 22:55:21.0
android 进程间通信---Service Manager(2)

关于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();
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;}
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端。

  

  相关解决方案