靠谱 的软件外包伙伴

您的位置:首页 > 新闻动态 > ActivityManager框架的解析

ActivityManager框架的解析

2016-08-18 11:41:43

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

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

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

ok先来张类图(网络搜索出来的) 
这里写图片描述

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
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

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

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

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

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

     public List<RunningServiceInfo> getRunningServices(int maxNum)throws SecurityException {
            try {
                return ActivityManagerNative.getDefault()
                        .getServices(maxNum, 0);
            } catch (RemoteException e) {
                // System dead, we will be dead too soon!
                return null;
            }
        }
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

    /**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6

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

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

    //ActivityManager的gDefault
    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;
        }
    };
    //Singleton类
    public abstract class Singleton<T> {
        private T mInstance;
        protected abstract T create();
        public final T get() {
            synchronized (this) {
                if (mInstance == null) {
                    mInstance = create();
                }
                return mInstance;
            }
        }
    }
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

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

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

输出结果

通过反射获取到的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);
    }
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

输出结果

因此这个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;
    }
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

如果看了上一篇文章,那么这一部分就很熟悉了,将要传输的参数写入到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<ActivityManager.RunningServiceInfo> list = getServices(maxNum, fl);
            reply.writeNoException();
            int N = list != null ? list.size() : -1;
            reply.writeInt(N);
            int i;
            for (i=0; i<N; i++) {
                ActivityManager.RunningServiceInfo info = list.get(i);
                info.writeToParcel(reply, 0);
            }
            return true;
        }
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

关于:中科研拓
深圳市中科研拓科技有限公司专注提供软件外包、app开发、智能硬件开发、O2O电商平台、手机应用程序、大数据系统、物联网项目等开发外包服务,十年研发经验,上百成功案例,中科院软件外包合作企业。通过IT技术实现创造客户和社会的价值,致力于为用户提供最佳的软件解决方案。联系电话400-0316-532,邮箱sales@zhongkerd.com,网址www.zhongkerd.com


  上一篇   [返回首页] [打印] [返回上页]   下一篇