前言
此篇博客是在上篇《模拟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
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这个内部类代理对象,有图为证:
通过反射获取到的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则创建一个代理返回。有图为证:
因此这个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框架。