ActivityManager 框架解析

前言
此篇博客是在上篇《模拟AIDL实现进程间通信》的基础上进行解析ActivityManager,ServiceManager,PackgeManager框架的。如有疑问请看上篇文章。如有错误之处谢谢指正,以免后排同学入坑。

正文ActivityManager
ok,这篇文章其实也就是了解整个Activity框架,在这里面涉及到的有进程间通信机制,代理模式,如果看了我上篇的《模拟AIDL实现进程间通信》那么这篇文章就能很好的理解这篇文章了。

ActivityManager:官方文档介绍到其作用,是与系统所有正在运行着的Acitivity进行交互,对系统所有运行中的Activity相关信息(Task,Memory,Service,App)进行管理和维护;提供了相应的接口用于获取这些信息。

ok先来张类图(网络搜索出来的)
《ActivityManager 框架解析》

ok,通过这个类图先说明下,IBinder,Binder,IInterface,ActivityManager是为可以与用户交互的,也就是可以直接导包进行使用,而IActivityManager,ActivityManagerProxy,ActivityManagerNative用户就不能进行导包使用了,而这个ActivityManagerService那就是在系统上面存在的了。

先贴下这些用户不能直接使用的源码位置(此位置为完全源码的位置,不是SDK里面的,不过IActivityManager,ActivityManagerNative,ActivityManagerProxy在SDK的OS包下能找到,至于为什么不能导包引用是因为在类的顶是那个加了{@hide},这个在编译完成打成jar包后就不能进行引用了)。

    IActivityManager:frameworks\base\core\java\android\app\IActivityManager.java

    ActivityManagerNative:frameworks\base\core\java\android\app\ActivityManagerNative.java

    ActivityManagerProxy:此源码位置在ActivityManagerNative.java文件夹中,但是不是内部类。

    ActivityManagerService:frameworks\base\services\core\java\com\android\server\am\ActivityManagerNative.java

Ok,先来介绍下这些类的关系,从上图了解到,IActivityManager继承了Interface接口。而ActivityManagerNative和ActivityManagerPorxy实现了这个IActivityManager接口。

ActivityManager持有的是这个ActivityManagerPorxy代理对象,这样,只需要操作这个代理对象就能操作其业务实现的方法。那么真正实现其也业务的则是ActivityManagerService。

咱们再来说说这个ActivityManagerNative这个类,他继承了Binder而Binder实现了IBinder接口。其子类则是ActivityManagerService。

OK,关系介绍完了,多的不说了,因为这个整个结构其实跟上一篇的文章其实差不多,再去细讲感觉有点多余,如果有懵逼的同学,请移步上一篇文章。

好了,直接通过一个流程我们来了解下他的结构吧。举个简单的例子,ActivityManager的getRunningServices方法,这个方法是用来获取正在运行的服务列表。以下是此方法代码。

     public List
    
      getRunningServices(int maxNum)throws SecurityException { try { return ActivityManagerNative.getDefault() .getServices(maxNum, 0); } catch (RemoteException e) { return null; } }
    

从以上代码片段可以看出获取运行服务方法是通过ActivityManagerNative.getDefault();方法获取的一个对象然后调用getServices(maxNum, 0);方法来获取的。我们先来看下getDefault()是做什么的。

    /**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

返回了一个IActivityManager对象,因此这个getServices(maxNum, 0);是IActivityManager接口的方法。

那么我们看下这个gDefault是什么,(这一块有点复杂哦,涉及到了两个代理对象,别搞懵了)

    
    private static final Singleton
    
      gDefault = new Singleton
     
      () { 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; } }; public abstract class Singleton
      
        { private T mInstance; protected abstract T create(); public final T get() { synchronized (this) { if (mInstance == null) { mInstance = create(); } return mInstance; } } }
      
     
    

从以上代码可以看出是一个单例对象,这个Singleton就以泛型来创建不同的单例(第一次看到这样写单例的,学习了)。

那么看下这个Create()方法里面都干了些什么,ServiceManager.getService(“activity”);通过ServiceManager的getService(“activity”)获取一个IBinder对象,这个IBinder对象上篇文章也讲了是获取的一个代理,而不是真正的IBinder,即为在Binder对象里面的一个BinderPorxy这个内部类代理对象,有图为证:
《ActivityManager 框架解析》

《ActivityManager 框架解析》

通过反射获取到的IBinder对象看的出来就是这个代理BinderProxy(如果这里有懵圈的同学可以移步看下上篇文章,至于怎么获取到这个代理的这里先不讲这个,有机会会讲到这个ServiceManager所以在这也不做多说了。)

获取到这个IBinder对象后调用了ActivityManagerNative的asInterface方法并传进去这个IBinder对象获得了一个IActivityManager对象,这也是获取代理对象,值不过这个代理对象不在是Binder的了,而是ActivityManagerNative的代理对像,看下这个方法

  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);
    }

上篇文章介绍到这个queryLocalInterface方法是IBinder对象的方法,其实现是在Binder里面,作用就是验证并获取这个descriptor标识的IActivityManager对象。(上面也说到了ActivityManagerPorxy实现了IActivityManger)如果不为null,则返回,为null则创建一个代理返回。有图为证:
《ActivityManager 框架解析》

《ActivityManager 框架解析》

因此这个ActivityManger里面获取运行服务列表里的getServices(maxNum, 0);是代理ActivityManagerPorxy对象调用的,那么看下这个方法做了什么。

    public List getServices(int maxNum, int flags) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(maxNum);
        data.writeInt(flags);
        mRemote.transact(GET_SERVICES_TRANSACTION, data, reply, 0);
        reply.readException();
        ArrayList list = null;
        int N = reply.readInt();
        if (N >= 0) {
            list = new ArrayList();
            while (N > 0) {
                ActivityManager.RunningServiceInfo info =
                        ActivityManager.RunningServiceInfo.CREATOR
                        .createFromParcel(reply);
                list.add(info);
                N
            }
        }
        data.recycle();
        reply.recycle();
        return list;
    }

如果看了上一篇文章,那么这一部分就很熟悉了,将要传输的参数写入到Parcel对象中,并使用在创建这个代理对象传进来的IBinder对象调用transact方法将参数写出去,GET_SERVICES_TRANSACTION为一个标识,也能说是命令。当写出去后ActivityManagerNative就会调用ontransact方法,然后通过GET_SERVICES_TRANSACTION进行判断执行其对应操作。

    case GET_SERVICES_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            int maxNum = data.readInt();
            int fl = data.readInt();
            List
    
      list = getServices(maxNum, fl); reply.writeNoException(); int N = list != null ? list.size() : -1; reply.writeInt(N); int i; for (i=0; i
     
    

getServices(maxNum, fl);调用的是ActivityManagerService里面的方法,然后就获得了。一个集合,并将这集合的内容一条条的写出去。然后接收。他们的Binder通信我就不细说了哈,上篇文章有详细写到。哈哈,这如果继续追踪源码下去就长了,我们这篇注重讲ActivityManager框架。

    原文作者:ActivityManagerService
    原文地址: https://juejin.im/entry/57bae5d4a34131005b1263cd
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞