引子
在分析activity的启动过程时,一定会看到如下代码:
../framewoks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; Uri referrer = target != null ? target.onProvideReferrer() : null; ... try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); // 这里分析的重点 int result = ActivityTaskManager.getService() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; }
直接来到ActivityTaskManager.getService(),这是我们今天要分析的主角。
../framewoks/base/core/java/android/app/ActivityTaskManager.java:
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
// 获取ATMS
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
从上面的代码可以看出,ATMS是确实是通过ServiceManager获取的。不过这里的ATMS是一个实现了IBinder接口的对象,然后通过asInterface转化成了一个Proxy对象(后面用于跨进程调用)。
IBinder b??
这里的b对象到底是什么东西呢?(不得不说面向对象的多态特性有时会让我们在阅读代码时不能直接看到对象的本质)
那就继续跟进ServiceManager.getService吧:
../framewoks/base/core/java/android/os/ServiceManager.java
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {// 这里
return Binder.allowBlocking(rawGetService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();final IBinder binder = getIServiceManager().getService(name);
...
return binder;
}
getIServiceManager().getService(name)分成两步:
1.getIServiceManager():
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
再分两步:
1.1 ServiceManagerNative.asInterface
ServiceManagerNative.java:
static public IServiceManager asInterface(IBinder obj)
{
...return new ServiceManagerProxy(obj);
}class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}public IBinder asBinder() {
return mRemote;
}
...
}
这里跟aidl文件生成的Stub类的方式如出一辙,同样通过asInterface方法构造了一个ServiceManagerProxy代理对象,而内部的mRemote对象是通过下面1.2方法得到的。还可以发现一点:这个mRemote对象和我们最终要分析的"b"对象类型应该是一致的,只不过一个对应的是servicemanager,一个对应的是atms。
继续往下分析:
1.2 BinderInternal.getContextObject()
public static final native IBinder getContextObject();
这是个native方法,源码见:
../framewoks/base/core/jni/android_util_Binder.cpp
这里是jni方法的注册,传入函数指针指向下面的方法
里面有个javaObjectForIBinder方法:
这个方法的作用就是将C层binder的对象转化成java对象, 这个c层的binder对象其实是一个Bpbinder,那么它将被转化成java层的什么类型的对象呢?
继续往下看:
答案一目了然,没错也是 BinderProxy对象,直接调用了getInstance方法构造。
到这里其实分析还没有结束,我们知道这里获取到的binder对象是servicemanger的,那怎么看出是servicemanager的呢?
还记得javaObjectForIBinder上面还有个方法吧:
../framewoks/native/libs/binder/ProcessState.cpp
getStrongProxyForHandle的参数直接传了0,说明service_manger作为Android系统服务的”大总管“,它的标识是固定的,并且是0,也正因如此它对任何进程都是”可见的“。
2.getService(name):
最后我们来看看这个atms的binder对象是否也是BinderProxy对象。
直接对应上面的源码:
class ServiceManagerProxy implements IServiceManager {
...
@UnsupportedAppUsage
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
...
}
reply.readStrongBinder()
最终也会调用一个native方法,源码如下:
../base/core/jni/android_os_Parcel.cpp
可以看到,最后还是调用了javaObjectForIBiner方法,得到了一个atms的BinderProxy对象。
ps:至于为什么是atms的,可以深入了解一下binder机制,本文不再赘述。