该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽可能按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深刻理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其余的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能须要有必定Android开发基础和项目经验的同窗才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师。java
咱们在上一篇中比较详尽的介绍了Android的消息机制,不过有一些内容咱们在不理解Android Binder的话是没法讲解清楚的。对于初学Android的朋友而言,最难却又最想掌握的恐怕就是Binder机制了,由于Android系统基本上能够看做是一个基于Binder通讯的C/S架构。 Binder就像网络同样,把系统的各个部分链接在了一块儿,所以它是很是重要的。咱们下面会Android Binder机制进行从上到下从易到难的分层次讲解,从而既能让初学者对Binder有必定认识,也能让有必定Android基础的人得到收获。
注:下文中的源码均出自android-6.0.0_r5linux
对于初学者来讲,深刻Android Binder机制是很是不明智的。Android Binder机制大都涉及Java层、Native层、驱动层这三三个方面,对于初学者来讲想啃这三块硬骨头很容易磕着牙。咱们这这一节概述从如下几个方面让你从比较宏观的角度理解Android Binder。android
在该系列博客中的第一章咱们就提及了Android进程相关问题,Android故意弱化了进程的概念,而用相对容易理解的四大组件。但是咱们在稍微深刻Android的时候,那么进程是绕不过的。默认状况下,同一个应用程序中的全部组件运行在同一个进程中,并且绝大多数的应用程序也都是这样的。这个默认进程是用这个应用的包名来命名的。程序员
咱们在运行App的时候常常须要使用一些系统服务,好比剪切板服务,而剪切板服务是运行在SystemServer进程中的。那咱们的App是怎么使用剪切板服务的呢,咱们都知道进程是相互独立的,静态变量等等都没法共用。这就涉及到进程间的通讯了,即IPC。咱们都知道Android是基于Linux内核的,那咱们简单介绍下Linux下的几种IPC机制。面试
管道是由内核管理的一个缓冲区,至关于咱们放入内存中的一个纸条。管道的一端链接一个进程的输出。这个进程会向管道中放入信息。管道的另外一端链接一个进程的输入,这个进程取出被放入管道的信息。安全
命名管道是一种特殊类型的文件,它在系统中以文件形式存在。这样克服了管道的弊端,他能够容许没有亲缘关系的进程间通讯。服务器
共享内存是在多个进程之间共享内存区域的一种进程间的通讯方式,由IPC为进程建立的一个特殊地址范围,它将出如今该进程的地址空间中。其余进程能够将同一段共享内存链接到本身的地址空间中。全部进程均可以访问共享内存中的地址,若是一个进程向共享内存中写入了数据,所作的改动将马上被其余进程看到。cookie
内存映射是由一个文件到一块内存的映射,在此以后进程操做文件,就像操做进程空间里的内存地址同样了。网络
套接字机制不但能够单机的不一样进程通讯,并且使得跨网机器间进程能够通讯。
套接字的建立和使用与管道是有区别的,套接字明确地将客户端与服务器区分开来,能够实现多个客户端连到同一服务器。数据结构
做为Android系统下的一种IPC机制,其本质上与上面罗列出的IPC机制并没有本质上的不一样,都是做为进程间通讯的一种手段。而且在Android系统中也不是只存在Binder这一种进程间通讯的方式,在有些地方也使用了Socket。既然Linux已经提供了众多IPC机制,那么Android 为什么还要使用Binder做为主要的进程间通讯的方式呢,那么固然有他的优势存在。
Java层Binder的功能,依赖于Native层Binder来实现,能够认为Java层Binder架构是Native层Binder架构的一个镜像。可是这并不影响咱们分析Android Java层Binder的功能。咱们用一个例子来讲明这个过程。
咱们在第一篇中就讲解了SystemServer这个进程,这个进程和zygote进程一块儿撑起了Android 世界,他们之中有一个崩溃,Android世界就会砰然倒塌。Android许多的重要的系统服务如AMS、PMS等都运行在SystemServer进程中。可是还有一个比较重要的进程ServiceManager进程(简称SM)跟zygote是兄弟进程。这个进程的做用是用来统一管理服务,如AMS。它们之间的关系以下。
咱们的AMS须要向SM进程中注册信息,其余进程若是想使用AMS,那么先和ServiceManager进程进行通讯查询,接着再和AMS所在SystemServer进程通讯。这部分关系图以下
咱们这里仅上图分析①②③中的一条道路,咱们来分析③,即咱们的应用进程(Client)如何与服务进程(Server)交互。
Java层的Binder,咱们来看涉及的类的结构图
[IBinder.java]
public interface IBinder { //交互函数 public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException; }
咱们接着来看Binder和BinderProxy 他们都声明在Binder.java中
[Binder.java]
/** Binder类 */ public class Binder implements IBinder { public final boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { ...... //这里调用了onTransact函数进行处理,通常状况下这个函数都会被它的子类重写 boolean r = onTransact(code, data, reply, flags); if (reply != null) { reply.setDataPosition(0); } return r; } } /** BinderProxy类 */ final class BinderProxy implements IBinder { public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { //直接以JNI的方式调用Native层的transact函数 return transactNative(code, data, reply, flags); } public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException; }
通用的IPC流程以下
如今假设下面一个场景,咱们的应用进程即咱们的App想要使用ActivityManagerService的startActivity函数(这种场景确定有的,当咱们拿到手机的时候,手机已经预装了许多App,其中Launcher App(桌面管理App)是在Android系统启动完成以后启动的第一个App,咱们安装好一个应用后,点击应用图标即发出Intent,想要启动另外一个App中的Activity,咱们在AndroidManifest.xml中注册了Main Activity)。Launcher App所在的进程要与AMS所在的进程SystemServer进程交互。
咱们来看这个例子。按照上面的通用流程咱们猜想Launcher进程与SystemServer进程交互过程也如上图所示,那么按照这个思路咱们来看。分为3点:
这一部分是咱们的上图中的test函数所声明的类或者接口,咱们的Client端代理和Server端服务都要实现这个函数。果真有
[IActivityManager.java]
public interface IActivityManager extends IInterface { public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException; ...... }
这里声明了咱们将要调用的业务函数startActivity,那么接着第二点
ActivityManagerProxy是在ActivityManagerNative.java中声明的内部类
class ActivityManagerProxy implements IActivityManager { public ActivityManagerProxy(IBinder remote) { mRemote = remote; } public IBinder asBinder() { return mRemote; } public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); data.writeString(callingPackage); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(startFlags); if (profilerInfo != null) { data.writeInt(1); profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { data.writeInt(0); } if (options != null) { data.writeInt(1); options.writeToParcel(data, 0); } else { data.writeInt(0); } //看这里果真是经过mRemote.transact函数,这里的mRemote是BinderProxy类,关于这一点咱们在Native层分析的时候再给出 mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; } ...... }
ActivityManagerNative是继承于Binder的抽象类,并重写了onTransact方法
public abstract class ActivityManagerNative extends Binder implements IActivityManager{ @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { //根据code处理相应的业务逻辑,咱们这里是START_ACTIVITY_TRANSACTION switch (code) { case START_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); String callingPackage = data.readString(); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); int startFlags = data.readInt(); ProfilerInfo profilerInfo = data.readInt() != 0 ? ProfilerInfo.CREATOR.createFromParcel(data) : null; Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null; int result = startActivity(app, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options); reply.writeNoException(); reply.writeInt(result); return true; } } }
既然ActivityManagerNative是个抽象类,那么谁真正实现了呢
[ActivityManagerService.java]
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { //重写了onTransact函数 @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { ...... try { //调用父类即ActivityManagerNative的onTransact函数 return super.onTransact(code, data, reply, flags); } catch (RuntimeException e) { throw e; } } }
Launcher进程与SystemServer进程交互过程以下
关于Java层的Binder机制,咱们只须要理解以BinderProxy表明的代理端和Binder表明的服务端的概念便可,例如咱们本例中的AMS,AMS是运行在SystemServer进程中的服务端,它间接继承于Binder,在获得相关请求后,会调用AMS重写的onTransact函数进行逻辑处理。那么这个请求就是是AMS的客户端ActivityManagerProxy经过Binder的方式发给它的,ActivityManagerProxy发送这个请求的方式,是经过调用其内部的成员变量mRemote,这个mRemote实际上是BinderProxy的对象,而后BinderProxy经过JNI调用Native层对应函数,最终经过Binder驱动达到与SystemServer交互的目的。
那么还遗留下如下几个问题:
1. 服务器端的代理怎么得到的
2. 位于代理类中的mRemote这个变量
要想理解好上面的个问题,咱们必须向Native层进军。
咱们依然以AMS分析,咱们先来想一下咱们在用户进程中即咱们的App中想使用AMS或者其余剪切板之类的系统服务函数了怎么办??按照上面的分析咱们要得到AMS的代理ActivityManagerProxy
[ActivityManagerNative.java]
//这里咱们的App进程从SM进程获得AMS服务对应的客户端代理BinderProxy IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); //以BinderProxy为参数获得咱们ActivityManagerProxy,并把BinderProxy对象存储在mRemote变量中 IActivityManager am = asInterface(b); return am;
到这里咱们就有如下问题,本小节分析1,2
1. 既然能够经过SM得到对应的客户端代理,那么AMS一定已经注册在SM中了,那么怎么注册的呢?
2. AMS代理是如何得到的?
3. AMS代理是如何与Binder通讯的?
咱们来一一分析,在分析问题以前咱们先作一个假设,这个假设相当重要,那就是无论咱们的SystemServer进程与SM进程交互也好仍是咱们的App进程与SM进程也好,SM的代理已经事先建立完毕,即无论咱们在SystemServer端仍是App端,在与SM进程交互的时候不用考虑代理怎么得到的。为何会有如此假设,由于我本身深受其害,因为上述三个过程均是经过Binder,很容易陷入思惟混乱。
咱们SystemServer进程中的AMS经过SM的代理与SM进程交互(读者也能够把这个过程想象为你所能理解的进程间通讯方式,例如管道、Socket等),并把本身注册在SM中
SystemServer建立出ActivityManagerService后,最终将调用其setSystemProcess方法:
[SystemServer.java]
public void setSystemProcess() { try { //注册服务,第二个参数为this,这里假设SystemServer经过“socket”与SM交互 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); .......... } catch (PackageManager.NameNotFoundException e) { ........ } }
上面的请求最终是经过SM服务代理发送的()
[ServiceManagerNative.java]
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { //将数据打包写入Parcel对象 Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); //注意这个地方,后文分析,此时的service为ActivityManagerService data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); //调用BindProxy的transact函数 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
上面的过程已经分析过了, 这里咱们主要看一下哪一个对应的native层的transact函数
[android_ util_Binder.cpp]
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) { ........ //将java对象转化为native对象 Parcel* data = parcelForJavaObject(env, dataObj); ......... Parcel* reply = parcelForJavaObject(env, replyObj); ........ //获得native层的BpBinder IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); ........ //经过BpBinder利用IPCThreadState,将请求经过Binder驱动发送给SM进程 status_t err = target->transact(code, *data, reply, flags); ........ }
SM进程收到信息后便处理这个消息(这个说法并不许确,准确的说法是,SM进程中主线程一直在与binder设备交互,想必读者也猜到了for(;;)),有消息时便经过预先定义好的函数进行处理
[service_manager.c]
switch(txn->code) { case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } handle = bio_get_ref(msg); allow_isolated = bio_get_uint32(msg) ? 1 : 0; //do_add_service if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid)) return -1; break; } int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle, uid_t uid, int allow_isolated, pid_t spid) { //结构体si,用来存储服务信息 struct svcinfo *si; //判断服务有没有权限注册,并非全部的服务都能注册 if (!svc_can_register(s, len, spid)) { return -1; } //查询服务有没有注册过 si = find_svc(s, len); if (si) {//已经注册过 if (si->handle) { ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n", str8(s, len), handle, uid); svcinfo_death(bs, si); } si->handle = handle; } else {//尚未注册过,咱们进入这个分支 si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); if (!si) { ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n", str8(s, len), handle, uid); return -1; } //保存一些handle等信息 si->handle = handle; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = '\0'; si->death.func = (void*) svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->next = svclist; svclist = si; } binder_acquire(bs, handle); binder_link_to_death(bs, handle, &si->death); return 0; }
看到这里SM貌似只保留了一些AMS的信息而已,实际上并不仅是如此,咱们来看一下上面的保留问题
[Parcel.java]
data.writeStrongBinder(service); public final void writeStrongBinder(IBinder val) { //调用了native函数 nativeWriteStrongBinder(mNativePtr, val); }
跟进[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) { //native层的parcel const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); if (err != NO_ERROR) { signalExceptionForError(env, clazz, err); } } } sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) { if (obj == NULL) return NULL; //obj为Binder类 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); //调用了JavaBBinderHolder的get方法 return jbh != NULL ? jbh->get(env, obj) : NULL; } //obj为BinderProxy类 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); } ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); return NULL; }
跟进[Pacel.cpp]
status_t Parcel::writeStrongBinder(const sp<IBinder>& val) { return flatten_binder(ProcessState::self(), val, this); } status_t flatten_binder(const sp<ProcessState>& /*proc*/, const sp<IBinder>& binder, Parcel* out) { flat_binder_object obj; obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; if (binder != NULL) {//binder不为空 IBinder *local = binder->localBinder();//是否是本地binder,本地的意思是同一个进程中的调用 if (!local) { BpBinder *proxy = binder->remoteBinder(); if (proxy == NULL) { ALOGE("null proxy"); } const int32_t handle = proxy ? proxy->handle() : 0; obj.type = BINDER_TYPE_HANDLE; obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ obj.handle = handle; obj.cookie = 0; } else {//咱们这里明显不是 obj.type = BINDER_TYPE_BINDER; obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); obj.cookie = reinterpret_cast<uintptr_t>(local); } } else {//错误信息 obj.type = BINDER_TYPE_BINDER; obj.binder = 0; obj.cookie = 0; } return finish_flatten_binder(binder, obj, out); }
经过上面的代码,咱们能够看到当一个服务进行注册时,会将Java层的Binder对象和Native层的BBinder关联起来,因而服务端绑定到了Native层的Binder架构。
此外,addService中打包传入的其实不是ActivityManagerService自己,而是对应的JavaBBinder对象。
这里对应的结构以下图所示:
咱们上面SystemServer中的AMS已经在SM中准备好了,那咱们ServiceManager.getService(Context.ACTIVITY_SERVICE);
同样的过程,咱们知道最终会在service_manager.c中处理
switch(txn->code) { //这里有个case穿透,,好吧 case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } //查询AMS保存在SM中对应的的那个handle handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid); if (!handle) break; bio_put_ref(reply, handle); return 0; } 把写入数据后的reply返回 bio_put_uint32(reply, 0);
回到咱们的调用处
[ServiceManagerNative.java]
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); //看这里readStrongBinder,是否是感受跟咱们上面的writeStrongBinder感受是一对的 IBinder binder = reply.readStrongBinder(); reply.recycle(); data.recycle(); return binder; }
Parcel的readStrongBinder仍是个JNI调用
[android_ os_Parcel.cpp]
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { //这里咱们看到了什么,,看函数名字应该是为Binder生成一个java对象吧 return javaObjectForIBinder(env, parcel->readStrongBinder()); } return NULL; }
咱们先看Pacel的readStrongBinder方法
[Parcel.cpp]
sp<IBinder> Parcel::readStrongBinder() const { sp<IBinder> val; //看到这里,还记得writeStrongBinder中的flatten_binder,这里是unflatten_binder unflatten_binder(ProcessState::self(), *this, &val); return val; } status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out) { const flat_binder_object* flat = in.readObject(false); if (flat) { switch (flat->type) { case BINDER_TYPE_BINDER: *out = reinterpret_cast<IBinder*>(flat->cookie); return finish_unflatten_binder(NULL, *flat, in); case BINDER_TYPE_HANDLE: //到这里咱们也清楚了进入这个分支 //调用ProcessState的getStrongProxyForHandle函数 *out = proc->getStrongProxyForHandle(flat->handle); return finish_unflatten_binder( static_cast<BpBinder*>(out->get()), *flat, in); } } return BAD_TYPE; }
继续跟进[ProcessState.cpp]
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { if (handle == 0) {//这里handle为0的状况是为SM准备的, Parcel data; status_t status = IPCThreadState::self()->transact( 0, IBinder::PING_TRANSACTION, data, NULL, 0); if (status == DEAD_OBJECT) return NULL; } //咱们的不为0,在这里建立了BpBinder b = new BpBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { result.force_set(b); e->refs->decWeak(this); } } return result; }
好了剩下最后一个了javaObjectForIBinder
[android_ util_Binder.cpp]
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { if (val == NULL) return NULL; //若是val是Binder对象,进入下面分支,此时val是BpBinder 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; } ......... //调用BpBinder的findObject函数 //在Native层的BpBinder中有一个ObjectManager,它用来管理在Native BpBinder上建立的Java BinderProxy对象 //findObject用于判断gBinderProxyOffsets中,是否存储了已经被ObjectManager管理的Java BinderProxy对象 jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = jniGetReferent(env, object); ............ //若是该Java BinderProxy已经被管理,则删除这个旧的BinderProxy android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } //建立一个新的BinderProxy对象 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if (object != NULL) { // 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对象注册到BpBinder的ObjectManager中,同时注册一个回收函数proxy_cleanup //当BinderProxy对象detach时,proxy_cleanup函数将被调用,以释放一些资源 val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); // Also remember the death recipients registered on this proxy sp<DeathRecipientList> drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); //将死亡通知list和BinderProxy联系起来 env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get())); // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); //垃圾回收相关;利用gNumRefsCreated记录建立出的BinderProxy数量 //当建立出的BinderProxy数量大于200时,该函数将利用BinderInternal的ForceGc函数进行一个垃圾回收 incRefsCreated(env); return object; } }
到这里总算都打通了整体流程以下
经过Java层的服务端代理最终调用到BpBinder.transact函数
[BpBinder.cpp]
status_t BpBinder:transact(uint32_t code,const Parcel&data,Parcel*reply,uint32_t flags){ if(mAlive){ //BpBinder把transact工做交给了IPCThreadState。 status_t status=IPCThreadState:self()->transact( mHandle,code,data,reply,flags);//mHandle也是参数 if(status==DEAD_OBJECT)mAlive=0; return status; } return DEAD_OBJECT; }
[IPCThreadState.cpp]
IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), mMyThreadId(gettid()), mStrictModePolicy(0), mLastTransactionBinderFlags(0) { pthread_setspecific(gTLS, this); clearCaller(); //mIn和mOut是两个Parcel。 把它当作是发送和接收命令的缓冲区便可。 mIn.setDataCapacity(256); mOut.setDataCapacity(256); } status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { ...... /* 注意这里的第一个参数BC_TRANSACTION,它是应用程序向binder设备发送消息的消 息码,而binder设备向应用程序回复消息的消息码以BR_开头。 消息码的定义在 binder_module.h中,请求消息码和回应消息码的对应关系,须要查看Binder驱动的实 现才能将其理清楚,咱们这里暂时用不上。 */ err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); ...... err = waitForResponse(NULL, NULL); ...... return err; } status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) { //binder_transaction_data是和binder设备通讯的数据结构。 binder_transaction_data tr; //果真,handle的值传递给了target,用来标识目的端,其中0是ServiceManager的标志。 tr.target.handle=handle; //code是消息码,是用来switch/case的! tr.code = code; tr.flags = binderFlags; tr.cookie = 0; tr.sender_pid = 0; tr.sender_euid = 0; const status_t err = data.errorCheck(); if (err == NO_ERROR) { tr.data_size = data.ipcDataSize(); tr.data.ptr.buffer = data.ipcData(); tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t); tr.data.ptr.offsets = data.ipcObjects(); } else if (statusBuffer) { tr.flags |= TF_STATUS_CODE; *statusBuffer = err; tr.data_size = sizeof(status_t); tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer); tr.offsets_size = 0; tr.data.ptr.offsets = 0; } else { return (mLastError = err); } //把命令写到mOut中,而不是直接发出去,可见这个函数有点名存实亡。 mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr)); return NO_ERROR; } status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { uint32_t cmd; int32_t err; while (1) { if ((err=talkWithDriver()) <NO_ERROR) break; err = mIn.errorCheck(); if (err < NO_ERROR) break; if (mIn.dataAvail() == 0) continue; //看见没?这里开始操做mIn了,看来talkWithDriver中 //把mOut发出去,而后从driver中读到数据放到mIn中了。 cmd = mIn.readInt32(); } } status_t IPCThreadState::talkWithDriver(bool doReceive) { binder_write_read bwr; //中间东西太复杂了,不就是把mOut数据和mIn接收数据的处理后赋值给bwr吗? status_t err; do { //用ioctl来读写 if (ioctl(mProcess->mDriverFD,BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR; else err = -errno; } while (err == -EINTR); //到这里,回复数据就在bwr中了,bmr接收回复数据的buffer就是mIn提供的 if (bwr.read_consumed > 0) { mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0); } return NO_ERROR; }
咱们本篇详细分析了Binder机制,从概述->Java层Binder->Native层Binder->Binder驱动,位于各层次的读者都能得到收获。
很差意思各位,下周有个比较重要的面试,因此暂时不会更新该系列的博客,可是也会更新其余博客。记录准备面试的过程当中须要用到的比较容易错误的知识。
此致,敬礼