美文网首页
AndroidM源码学习——AMS之代理模式

AndroidM源码学习——AMS之代理模式

作者: 奥利奥真好吃 | 来源:发表于2018-01-17 14:26 被阅读0次
AMS之代理模式.png
  • IActivityManager是ActivityManagerNative与ActivityManagerProxy共同的接口
  • ActivityManagerPorxy含有一个IBinder对象mRemote,而抽象类ActivityManagerNative继承了IBinder的实现类Binder,这就决定了当Proxy发起调用后将由Native的实现类来接受调用
  • 本地客户端:ActivityManager
  • 远程服务端:ActivityManagerService
  • 代理类:ActivityManagerNative的内部类ActivityManagerProxy,它接受客户端的“委托”向服务端发起调用
  • 客户端与服务端通过Binder机制进行跨进程通信:以客户端调用getRecentTasks()为例
  1. ActivityManager发起本地调用
    public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
            throws SecurityException {
        try {
            return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
                    flags, UserHandle.myUserId());
        } catch (RemoteException e) {
            // System dead, we will be dead too soon!
            return null;
        }
    }
  1. ActivityManagerNative获取ActivityManagerServicer的本地代理
    static public IActivityManager getDefault() {
        return gDefault.get();
    }   
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }
  1. 代理ActivityManagerProxy对象使用Binder的transact方法向远端发起调用
    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
            int flags, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(maxNum);
        data.writeInt(flags);
        data.writeInt(userId);
        mRemote.transact(GET_RECENT_TASKS_TRANSACTION, data, reply, 0);
        reply.readException();
        ArrayList<ActivityManager.RecentTaskInfo> list
            = reply.createTypedArrayList(ActivityManager.RecentTaskInfo.CREATOR);
        data.recycle();
        reply.recycle();
        return list;
    }
  1. ActivityManagerNative使用onTransact()方法接受远程调用
        case GET_RECENT_TASKS_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            int maxNum = data.readInt();
            int fl = data.readInt();
            int userId = data.readInt();
            List<ActivityManager.RecentTaskInfo> list = getRecentTasks(maxNum,
                    fl, userId);
            reply.writeNoException();
            reply.writeTypedList(list);
            return true;
        }
  1. 由于ActivityManagerNative是一个抽象类,因此getRecentTasks()的具体实现在它的子类ActivityManagerService中
@Override
    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
        final int callingUid = Binder.getCallingUid();
        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
                false, ALLOW_FULL_ONLY, "getRecentTasks", null);

        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
        ···

相关文章

网友评论

      本文标题:AndroidM源码学习——AMS之代理模式

      本文链接:https://www.haomeiwen.com/subject/jdtuoxtx.html