源码分析 — Binder机制(二)之IActivityManager

一、概述

阅读本文前,请先阅读 《源码分析 — Binder机制(一)进程间通信》 的前半部分,对 Binder机制 有一个直观的了解,这有助于本文的阅读;

涉及到的知识点:

  1. 《源码分析 — Binder机制(一)(进程间通信)》
  2. 《Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析》

二、类图

这里写图片描述

说明:

  1. Binder 是一种基于 C/S的架构,分为 Client、Service、Binder驱动 三部分;
  2. Client 持有 IActivityManager 接口的远程服务的代理类 ActivityManagerProxy
  3. IActivityManager 接口的远程服务类是 ActivityManagerService
  4. 代理类 ActivityManagerProxy 内部持有一个Binder 的代理对象 BinderProxy,用于和远程服务 ActivityManagerService 的通信;
  5. ServiceManager 类用于管理远程服务;

三、时序图

这里写图片描述

四、源码分析

涉及到的类:

  1. Singleton
  2. ActivityManagerNative
  3. ActivityManagerProxy
  4. ActivityManagerService

4.1 类 Singleton

在看是之前,我们先来看一下类 Singleton,这个一个单例的抽象类;

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();
    // 调用get()方法就能获取到实例;
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                // 在子类中创建具体的实例;
                mInstance = create();
            }
            return mInstance;
        }
    }
}

4.2 类 ActivityManagerNative

public abstract class ActivityManagerNative extends Binder implements IActivityManager {
    // 获取ActivityManagerProxy对象;
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        // 返回接口IActivityManager的一个实现类;
        return new ActivityManagerProxy(obj);
    }

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
            case START_ACTIVITY_TRANSACTION: {
                data.enforceInterface(IActivityManager.descriptor);
                // 取出的b是ApplicationThread实例
                IBinder b = data.readStrongBinder();
                // 将b作为参数传入ApplicationThreadProxy对象;
                IApplicationThread app = ApplicationThreadNative.asInterface(b);
                String callingPackage = data.readString();
                // ...从data中读取数据...

                // 调用AMS.startActivity();
                int result = startActivity(app, callingPackage, intent, resolvedType,
                        resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
                // 将AMS返回的数据谢谢如reply中,让ActivityManagerProxy获取AMS返回的结果;
                reply.writeNoException();
                reply.writeInt(result);
                return true;
            }
            // ...
        }
        return super.onTransact(code, data, reply, flags);
    }

    // 这里就是Singleton的子类(匿名内部类)
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            // b 是一个BinderProxy对象;
            IBinder b = ServiceManager.getService("activity");
            // 调用asInterface(),返回ActivityManagerProxy实例;
            IActivityManager am = asInterface(b);
            return am;
        }
    };
}

4.3 类 ActivityManagerProxy


class ActivityManagerProxy implements IActivityManager {

    // mRemote是BinderProxy对象;
    private IBinder mRemote;

    public ActivityManagerProxy(IBinder remote) {
        mRemote = remote;
    }

    /*
     * 参数caller是ApplicationThread实例;
     * 具体赋值的地方,请查看Activity.startActivityForResult()方法;
     */
    public int startActivity(IApplicationThread caller, ...) throws RemoteException {
        // 通过Parcel类型的数据结构,进行数据传输;
        // data用于写入数据传递给远程服务端;
        Parcel data = Parcel.obtain();
        // reply用于接收远程服务端回传的数据;
        Parcel reply = Parcel.obtain();
        // 将Binder写入Parcel对象中;
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        // ...
        // 调用binderProxy.transact() --> Binder驱动层 --> Binder.execTransact() 
        // --> AMS.onTransact() --> AMS.startActivity()
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        // 当远程服务返回数据后,从reply中读取;
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }
}

4.4 类 ActivityManagerService

public final class ActivityManagerService extends ActivityManagerNative {

    // 最终调用到AMS的startActivity()方法
    @Override
    public final int startActivity(IApplicationThread caller, ...) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
    }
}

至此,一次应用进程到AMS进程的通信就已经完成了;

由于 IApplicationIActivityManager 类似,这里就不再分析;

五、ActivityManagerServiceApplicationThread 的跨进程通信

这里写图片描述

小结:

  1. Binder 是单向通信的,所以要实现跨进程相互传输信息,就需要两套 Binder 通道;
  2. 应用进程 –> AMS进程:通过ActivityManagerProxy(AMP) 去访问 ActivityManagerService(AMS)
  3. AMS进程 –> 应用进程:通过ApplicationThreadProxy(ATP) 去访问 ApplicationThread(AT)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Binder是Android操作系统中的一个IPC(进程间通信)机制,用于实现进程之间的通信和数据传输。Binder源码主要位于frameworks/native目录下。 在Binder源码中,最核心的部分是Binder驱动和Binder服务。Binder驱动是位于内核空间的组件,负责处理进程间的数据传输和交互。Binder服务是位于用户空间的组件,负责提供接口和功能来进行进程间通信。 在Binder源码中,主要涉及到以下几个重要的文件和目录: 1. drivers目录:包含了Binder驱动的代码,其中最重要的文件是binder.c,它实现了Binder驱动的核心逻辑。 2. include目录:包含了Binder的头文件,其中最重要的文件是binder.h,它定义了Binder的接口和数据结构。 3. libbinder目录:包含了Binder服务的代码,其中最重要的文件是IBinder.cpp和BpBinder.cpp,它们分别实现了Binder服务的接口和代理类。 4. services目录:包含了一些系统级别的Binder服务,例如Package Manager Service和Activity Manager Service。 如果你想深入了解Android Binder源码,可以参考以下资源: 1. Android 源码:你可以从Android官网或者GitHub上获取Android源码,并在frameworks/native目录下查看Binder相关的代码。 2. Android系统架构指南:Android官网提供了关于Android系统架构的详细文档,其中有关IPC和Binder的章节对于理解Binder的实现原理和源码结构很有帮助。 3. 《深入理解Android:卷2》一书中有关于Binder的详细介绍和源码解析,可以作为参考资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值