博客内容基于Android 8.0
因此,在分析AMS的时候和网上不一样,现在的客户端使用AMS的方法通过AIDL的方式,具体可以参考IActivityManager.aidl
Java 层的Binder 必然和Native 层的Binder有关,在分析流程的时候要时刻回忆着Native中的相关流程,这样才能更加通透的理解
一、Java层Binder的初始化
java层的Binder只是native层的一个镜像,具体的实现靠的还是native层,所以native层和java层必然有所联系,这种联系可以猜想一下靠的是JNI方式
《深入理解》书中已经指出是register_android_os_Binder函数专门负责搭建Java Binder和Native Binder交互关系
那么这个函数是什么时候被调用的呢?搜索后发现在[AndroidRuntime.cpp]
中有REG_JNI(register_android_os_Binder)
REG_JNI是一个宏,先不说REG_JNI,REG_JNI(register_android_os_Binder)在数组gRegJNI中,这个数组会被函数register_jni_procs调用,看看这个方法:
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
for (size_t i = 0; i < count; i++) {
//这里就会调用数组中的方法
if (array[i].mProc(env) < 0) {
\#ifndef NDEBUG
ALOGD("----------!!! %s failed to load\n", array[i].mName);
\#endif
return -1;
}
}
return 0;
}
再向上逆推 ,register_jni_procs被AndroidRuntime::startReg调用,再向上,则是被AndroidRuntime::start调用
start方法第一句是”ALOGD(“>>>>>> START %s uid %d <<<<<<\n”,”,这个在开机log中能看到
联想到开机流程,我们发现在zyote的main函数中,初始化Java虚拟机后,会注册一些JNI函数
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
再回头来看register_android_os_Binder
[android_util_Binder.cpp]
int register_android_os_Binder(JNIEnv* env)
{
//初始化Java Binder类和Native层的关系
if (int_register_android_os_Binder(env) < 0)
return -1;
//初始化Java BinderInternal类和Native层的关系
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
//初始化Java BinderProxy类和Native层的关系
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
……
}
这三个函数更详细的解释参见《深入理解》总结如下:
至此,Java Binder几个重要成员的初始化已完成,同时在代码中定义了几个全局静态对象,分别是gBinderOffsets、gBinderInternalOffsets和gBinderProxyOffsets。
框架的初始化其实就是提前获取一些JNI层的使用信息,如类成员函数的MethodID,类成员变量的fieldID等。这项工作是必需的,因为它能节省每次使用时获取这些信息的时间。当Binder调用频繁时,这些时间累积起来还是不容小觑的。
先记住这三个函数,以及这三个变量名,下面也会出现,到时候再说
二、举个栗子
1.Java层注册Service
下面通过一个AMS的实例来分析具体流程:
在ActivityManagerService.java中有setSystemProcess方法:
public void setSystemProcess() {
try {
//将ActivityManagerService服务注册到ServiceManager中
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
……
}
……
}
之前分析Native Service的时候知道,有一个ServiceManager负责管理所有的service
所以 ServiceManager.addService方法必然会将服务注册到ServiceManager中,来看看具体流程:
[ServiceManager.java]
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
先看看getIServiceManager返回了什么
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manage
sServiceManager = ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
下面分三个知识点来详细分析
- getContextObject
- asInterface
- addService
1.1 getContextObject分析
BinderInternal.getContextObject()是一个native函数,具体实现在:
[android_util_Binder]
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
注意到ProcessState::self()->getContextObject,联想到之前分析defaultServiceManager()也会执行这个
因此这里的作用是,传入参数为NULL(0),获取ServiceManager进程对应的BpBinder
javaObjectForIBinder的作用是利用env和BpBinder,构造出Java对象,来细看一下:
【插入一下】下面总是出现gBinderProxyOffsets,还记得这在哪出现过吗?
是的,在最开始初始化java层Binder的时候,详细看一下:
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass;
jmethodID mConstructor;
jmethodID mSendDeathNotice;
// Object state.
jfieldID mObject;
jfieldID mSelf;
jfieldID mOrgue;
} gBinderProxyOffsets;
初始化的地方在int_register_android_os_BinderProxy函数中,这个函数名这么熟悉,还记得在哪吗?是在register_android_os_Binder中
来详细看一下int_register_android_os_BinderProxy方法:
[android_util_Binder.cpps.cpp]
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
"Ljava/lang/ref/WeakReference;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
……
}
通过上面的赋值,最终得到的gBinderProxyOffsets如下:
{
jclass mClass; //android.os.BinderProxy
jmethodID mConstructor; //android.os.BinderProxy.<init>() 这个init方法在哪,指的是BinderProxy的构造方法吗?
jmethodID mSendDeathNotice; //android.os.BinderProxy.sendDeathNotice()
jfieldID mObject; //android.os.BinderProxy.mObject
jfieldID mSelf; //android.os.BinderProxy.mSelf
jfieldID mOrgue; //android.os.BinderProxy.mOrgue
}
可以明显看出gBinderProxyOffsets对应的就是java层的BinderProxy类
镜头转回来继续看javaObjectForIBinder
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
// For the rest of the function we will hold this lock, to serialize
// looking/creation/destruction of Java proxies for native Binder proxies.
AutoMutex _l(mProxyLock);
// Someone else's... do we know about it?
/*
val对象实际类型是上面通过`ProcessState::self()->getContextObject`得到的BpBinder
事实上,在Native层的BpBinder中有一个ObjectManager,它用来管理在Native BpBinder
上创建的Java BpBinder对象。下面这个findObject用来判断gBinderProxyOffsets
是否已经保存在ObjectManager中。如果是,那就需要删除这个旧的object
*/
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) {
jobject res = jniGetReferent(env, object);
if (res != NULL) {
ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
return res;
}
LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
//创建一个新的BinderProxy对象,并注册到Native BpBinder对象的ObjectManager中
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
// The proxy holds a reference to the native object.
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
val->incStrong((void*)javaObjectForIBinder);
// The native object needs to hold a weak reference back to the
// proxy, so we can retrieve the same proxy if it is still active.
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
/*
将这个新创建的BinderProxy对象注册(attach)到BpBinder的ObjectManager中,
同时注册一个回收函数proxy_cleanup。当BinderProxy对象撤销(detach)的时候,
该函数会 被调用,以释放一些资源。
*/
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
// Also remember the death recipients registered on this proxy
//DeathRecipientList保存了一个用于死亡通知的list
sp<DeathRecipientList> drl = new DeathRecipientList;
//将死亡通知list和BinderProxy对象联系起来
drl->incStrong((void*)javaObjectForIBinder);
env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
// Note that a new object reference has been created.
//增加该Proxy对象的引用计数
android_atomic_inc(&gNumProxyRefs);
//下面这个函数用于垃圾回收。创建的Proxy对象一旦超过200个,该函数
//将调用BinderInter类的ForceGc做一次垃圾回收
incRefsCreated(env);
}
return object;
}
总结:以上函数完成了以下两个工作:
· 创建了一个Java层的BinderProxy对象。
· 通过JNI,该BinderProxy对象和一个Native的BpBinder对象挂钩,而该BpBinder对象的通信目标就是ServiceManager。
1.2 asInterface分析
再来看一下ServiceManagerNative.asInterface
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
public ServiceManagerProxy(IBinder remote) {
//保存BinderProxy对象
mRemote = remote;
}
和分析native层的interface_cast一样,我们先缕一缕:
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
-->getIServiceManager().addService(name, service, allowIsolated);
-->ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject())).addService(name, service, allowIsolated)
-->ServiceManagerNative.asInterface(BinderInternal.getContextObject()).addService(name, service, allowIsolated) -->ServiceManagerNative.asInterface(new BinderProxy()).addService(name, service, allowIsolated)
-->new ServiceManagerProxy(new BinderProxy()).addService(name, service, allowIsolated)
所以最终调用的是ServiceManagerProxy.addService()
1.3 addService分析
[ServiceManagerNative.java]
ServiceManagerProxy::
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
//注意下面这个writeStrongBinder函数,service是AMS
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
//mRemote实际上就是BinderProxy对象,调用它的transact,将封装好的请求数据发送出去
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
跟一下transact
[BinderProxy.transact]
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
……
return transactNative(code, data, reply, flags);
……
}
transactNative是一个native函数,定义在:
[android_util_Binder.cpp]
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
……
//从Java的Parcel对象中得到Native的Parcel对象
Parcel* data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
//从Java的BinderProxy对象中得到之前已经创建好的那个Native的BpBinder对象
//(在android_os_BinderInternal_getContextObject中创建的)
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
……
//printf("Transact from Java code to %p sending: ", target); data->print();
//通过Native的BpBinder对象,将请求发送给ServiceManager
status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
……
}
总结一下,上面跟踪的是如何添加服务到ServiceManager中
老规矩,一张图总结上面流程:
1.4 换个角度看addService
不知道大家有没有注意到,我们最初addService的时候有一个重要的参数:
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
通过整个流程下来,用到的地方在ServiceManagerProxy.addService中的data.writeStrongBinder(service)
这个this代表什么呢?writeStrongBinder又在做什么呢?下面来分析一下
这个this自然指的是ActivityManagerSerivce,看一下AMS的继承结构:
public class ActivityManagerService extends IActivityManager.Stub
这里Android O和Android N 有改动,Android N 中是
public final class ActivityManagerService extends ActivityManagerNative
public abstract class ActivityManagerNative extends Binder implements IActivityManager
public interface IActivityManager extends IInterface
Android O 中,使用了aidl,原理应该和Android N一样,先按照Android N 分析(此处有疑问)
从编译IActivityManager.aidl生成的IActivityManager.java来看
public static abstract class Stub extends android.os.Binder implements android.app.IActivityManager
AMS会继承java层的Binder,自然会调用Binder的构造函数:
public Binder() {
init();
……
}
这个init()是native方法:
[android_util_Binder.cpp]
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
//创建一个JavaBBinderHolder对象
JavaBBinderHolder* jbh = new JavaBBinderHolder();
……
jbh->incStrong((void*)android_os_Binder_init);
//将这个JavaBBinderHolder对象保存到Java Binder对象的mObject成员中
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
从上面的代码可以看出,Java的Binder对象将和一个Native层的JavaBBinderHolder对象关联。
看一下JavaBBinderHolder:
class JavaBBinderHolder : public RefBase
{
public:
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
//创建一个JavaBBinder,obj实际上是Java层中的Binder对象
b = new JavaBBinder(env, obj);
mBinder = b;
……
}
return b;
}
……
private:
Mutex mLock;
wp<JavaBBinder> mBinder;
};
由于JavaBBinderHolder不属于Binder架构,暂时先不看,转身看看writeStrongBinder方法
[Parcel.java]
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val); //native方法
}
[android_os_Parcel.cpp]
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
跟踪ibinderForJavaObject
[android_util_Binder.cpp]
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
//如果Java的obj是Binder类,则首先获得JavaBBinderHolder对象,然后调用
//它的get函数(没忘吧,在JavaBBinderHolder的定义中)。而这个get将返回一个JavaBBinder
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
//如果obj是BinderProxy类,则返回Native的BpBinder对象
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
而我们传入的AMS是Binder类型,所以addService实际添加到Parcel的并不是AMS本身,而是一个叫JavaBBinder的对象。正是将它最终传递到Binder驱动。
通过JavaBBinder的构造方法可以看到,JavaBBinder会把传进来的service引用赋值给自己的mObject
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
……
}
综上,可以看到这三个类的关系如下图:
【插入一下】【多设计一个JavaBBinderHolder的原因】
《深入理解》“为什么不直接让Java层的Binder对象指向Native层的JavaBBinder对象呢?由于缺乏设计文档,这里不便妄加揣测,但从JavaBBinderHolder的实现上来分析,估计和垃圾回收(内存管理)有关,因为JavaBBinderHolder中的mBinder对象的类型被定义成弱引用wp了”
3. AMS响应请求
看到这个Bbinder,不知道大家有没有似曾相识的感觉,在分析Native Service的时候,我们的Native Service最终继承的就是Bbinder,比如MediaPlayerService
在Native Service中,客户端使用服务的时候,是用remote()->transact()
来调用服务端对应的方法
这个过程不在细说,Native Service中请求并响应简单流程如下:
remote()->transact()->BBinder.transact->BBinder.onTransact->BnMediaPlayerService.onTransact(BnMediaPlayerService继承Bbinder)
而在java层这里,在Java Serivce注册的时候,我们注册的是JavaBBinder,它是BBinder的子类。JavaBBinder并没有重写transact()函数,Transact()调用onTransact()函数。JavaBBinder重写了onTransact()的实现,这样,请求并响应流程如下:
remote()->transact()->BBinder.transact->BBinder.onTransact->JavaBBinder.onTransact
所以要看下JavaBBinder.onTransact
[android_util_Binder.cpp]
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
//从Java虚拟机中得到调用JNI函数所需的结构体
JNIEnv* env = javavm_to_jnienv(mVM);
.......
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
.......
}
看到CallBooleanMethod就知道要回调java层 段函数,看看通过JNI回调的是哪个函数:
很容易就找到了gBinderOffsets.mExecTransact赋值的地方:
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
在int_register_android_os_Binder中(看这个函数名又是似曾相识,是在刚开始的register_android_os_Binder中调用,所以说这个函数的作用是完成重要成员的初始化)
所以,最终通过JNI调用了Binder的execTransact方法
接下来就进入java层了
[Binder.java]
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
.........
try {
//调用子类的onTransact函数
res = onTransact(code, data, reply, flags);
}..........
}
所以会调用AMS的onTransact方法,接着向父类调用onTransact …… 不再分析了
总结:
上面缕一缕得到的结果是:
new ServiceManagerProxy(new BinderProxy()).addService(name, service, allowIsolated)
联想到Native Service,我们在addService的时候是这样说的:
defaultServiceManager()->addService
defaultServiceManager()实际返回的对象是BpServiceManager,BpServiceManager里面有mRemote变量是BpBinder类型
而ServiceManagerProxy中也有个mRemote变量,这个变量被初始化为BinderProxy类型,而mRemote又存储到BpBinder的ObjectManager中
所以,Java层的流程和Native几乎是一样的
整理结构图如下:
让我们用最后一个小栗子来结束
在分析MediaPlayerService的时候,有看到过使用checkService来检查服务是否存在
Java层同样存在这个功能,看看它怎么实现的:
接口是在:
[ServiceManager]
public static IBinder checkService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(getIServiceManager().checkService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in checkService", e);
return null;
}
}
调用了getIServiceManager().checkService(name)
前面已经分析过getIServiceManager返回的是ServiceManagerProxy类型
[ServiceManagerNative.java]
public IBinder checkService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
似曾相识吧,再看一下Native中BpServiceManager的方法:
[IServiceManager.cpp]
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}