结合Binder机制看ActivityManager

Posted Jason_Lee155

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结合Binder机制看ActivityManager相关的知识,希望对你有一定的参考价值。

一、概述

阅读本文前,请先阅读 《结合Binder机制看ActivityManager(一)》 的前半部分,对 Binder机制 有一个直观的了解,这有助于本文的阅读;

二、类图

说明:

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

三、时序图

四、源码分析

涉及到的类:

  • 类 Singleton;
  • 类 ActivityManagerNative;
  • 类 ActivityManagerProxy;
  • 类 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进程的通信就已经完成了;

由于 IApplication 与 IActivityManager 类似,这里就不再分析;

五、ActivityManagerService 与 ApplicationThread 的跨进程通信

小结:

  • Binder 是单向通信的,所以要实现跨进程相互传输信息,就需要两套 Binder 通道;
  • 应用进程 –> AMS进程:通过ActivityManagerProxy(AMP) 去访问 ActivityManagerService(AMS);
  • AMS进程 –> 应用进程:通过ApplicationThreadProxy(ATP) 去访问 ApplicationThread(AT);

以上是关于结合Binder机制看ActivityManager的主要内容,如果未能解决你的问题,请参考以下文章

结合Binder机制看ActivityManager

Android 使用binder访问service的方式

图文结合:通俗易懂的Android多进程间通信--binder机制

Android Binder机制完全解析

Binder机制在AIDL中的实现分析

Binder机制在AIDL中的实现分析