zoukankan      html  css  js  c++  java
  • 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端。

      

  • 相关阅读:
    Chrome快捷键
    Nginx之基本介绍(一)
    windows程序调试
    python有序字典
    value是列表的字典排序
    构造Map并对其排序
    python读取文件时遇到非法字符的处理 UnicodeDecodeError: 'gbk' codec can't decode bytes in position
    python正则表达式 分割字符串
    python3 导入模块
    python3 以utf-8编码写文件
  • 原文地址:https://www.cnblogs.com/deman/p/4792400.html
Copyright © 2011-2022 走看看