ActivityManager

建议阅读:

ServiceManager(看这个能对ActivityManager有更好的理解)

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包后就不能进行引用了)。

1
2
3
4
5
6
7
8
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()是做什么的。

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

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

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

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
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这个内部类代理对象,有图为证:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
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则创建一个代理返回。有图为证:

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

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
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进行判断执行其对应操作。

1
2
3
4
5
6
7
8
9
10
11
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框架。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器