• 《深入理解Android2》读书笔记(二)


    接之前那篇《深入理解Android2》读书笔记(一)

    下面几篇来分别详细分析

    Binder类作为服务端的Bn的代表,BinderProxy类作为客户端的Bp的代表,BinderInternal类仅供Binder架构使用,GcWatcher专门用于处理和Binder架构相关的垃圾回收,Parcel类用于承载通信数据。FLAG_ONEWAY标志如果被指明,则调用方只要把请求发送到Binder驱动即可返回,而不用等待服务端的结果,是一种所谓的非阻塞方式,所以客户端一般会向服务端注册一个回调。

    在java层binder正式工作之前,Native层Binder和Java层Binder需要建立关系,将会调用一些JNI函数,Binder类、BinderInternal类、BinderProxy类依次初始化。

    将AMS服务注册到ServiceManager中(整个Android系统中有一个Native的ServiceManager(SM)进程,它统筹管理Android系统上的所有Service。成为一个Service的必要条件是在SM中注册)。

    SM注册服务

    ServiceManager

    public static void addService(String name, IBinder service, boolean allowIsolated) {
        try {
            getIServiceManager().addService(name, service, allowIsolated);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }
    
    private static IServiceManager getIServiceManager() {
        ...
        // Find the service manager
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

    BinderInternal.getContextObject函数完成了两个工作

    1.创建了一个java层的binderProxy对象

    2.通过JNI,该BinderProxy对象和一个Native的BpProxy对象挂钩,而该BpProxy对象的通信目标就是ServiceManager。

    static public IServiceManager asInterface(IBinder obj){
        ...
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        
        return new ServiceManagerProxy(obj);
    }

    ServiceManagerProxy

    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

    addService实际添加到Parcel的并不是AMS本身,而是一个名为JavaBBinder的对象。addService正是该JavaBBinder对象最终传递到Binder驱动。

    当收到请求时,系统会调用JavaBBinder的onTransact函数,最终在Binder类中实现

    private boolean execTransact(int code, long dataObj, long replyObj,
            int flags) {
        Parcel data = Parcel.obtain(dataObj);
        Parcel reply = Parcel.obtain(replyObj);
        boolean res;
        try {
            res = onTransact(code, data, reply, flags);
        }
        ...
        checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
        reply.recycle();
        data.recycle();
        StrictMode.clearGatheredViolations();
        return res;
    }

    ActivityManagerNative类实现了onTransact函数

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            int startFlags = data.readInt();
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            Bundle options = data.readInt() != 0
                    ? Bundle.CREATOR.createFromParcel(data) : null;
            int result = startActivity(app, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }
        ...

    JavaBBinder仅是一个传声筒,本身不实现任何业务函数,其工作是:

    1.收到请求时,简单调用它所绑定的java层binder对象的execTransact

    2.该binder对象的execTransact调用其子类实现的onTransact函数

    3.子类的onTransact函数将业务又派发给其子类来完成

    通过这种方式,来自客户端的请求就能传递到正确的Java层Binder对象了。

    AMS响应请求的流程

    Java层Binder架构总结

    1.对于代表客户端的BinderProxy来说,Java层的BinderProxy在Native层对应一个BpBinder对象。凡是从Java层发出的请求,首先从Java层的BinderProxy传递到Native层的BpBinder,继而由BpBinder将请求发送到Binder驱动。

    2.对于代表服务端的Service来说,Java层的Binder在Native层有一个JavaBBinder对象。所有Java层的Binder在Native层都对应为JavaBBinder,而JavaBBinder仅起到中转作用,即把来自客户端的请求从Native层传递到Java层。

    3.系统中依然只有一个Native的ServiceManager。

    MessageQueue的部分在我的另一篇博客中已经分析过了,可移步handler机制

  • 相关阅读:
    代码审计中的SQL注入
    74cms_3.5.1 宽字节注入
    熊海CMS_1.0 代码审计
    201521123096《Java程序设计》第七周学习总结
    201521123096《Java程序设计》第四周学习总结
    一个例子
    201521123096《Java程序设计》第一周学习总结
    201521123096《Java程序设计》第五周学习总结
    201521123096《Java程序设计》第六周学习总结
    201521123096《Java程序设计》第二周学习总结
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/6927720.html
Copyright © 2020-2023  润新知