前面的一~五章已经基本将Binder通信的上层逻辑解释清楚了,接下来的重点是分析binder的上层 是如何走到native层的,换一句话说,native层如何被封装成为上层的。也就是Binder的 Java和Native层的相互转化。
当讲到Binder的java&Native层的通信,天生最好研究的就是ServiceManager类了,因为,它是运用最广泛的也是大家最熟悉的使用了Binder通信的场景。
大家不妨先来看这个图:
通过上图,我们不难发现,在Binder通信必然需要有JNI层的支撑,缺乏JNI层,将无法完成java到Native层的调用,因此我们必须研究一下Java framework层与Native层之间的相互调动。
1)Client端通过ServiceManager 拿到Server端服务的Binder 代理,也就是BinderProxy(是Server端Binder的一个代理);
2)这个BinderProxy的访问需要经过JNI层的Android_util_binder类将请求转交给native的BpBinder(p代表代理的意思);
3)BpBinder会通过ioctl将请求转交给Binder驱动设备;
4)在服务端注册了一个监听请求的回调函数,一旦驱动层收到BpBinder 的调用,就会回调BBInder注册的回调函数,于是,就将请求转给了BBinder;
5)BBinder拿到请求后,会进行一些数据的处理,然后通过JNI将请求转交给了java类;
6)java层会通过aidl中的函数将请求发送给Server端的实现者,由Server端通过stub 去调用相关的执行代码,并将结果通过类似的路径返回。
以上只是一个大概的流程,具体的实现流程我们将在后面的分析中更详细的介绍。然而要全面的分析这个流程最好的案例便是ServiceManager。
2. ServcieManager场景
在跨进程通信过程中,比如我们与AMS通信,首先需要拿到AMS的binder,然而,AMS的binder往往是通过ServcieManager获取的,因此会有代码:
scss
ServiceManager.getService(Context.ACTIVITY_SERVICE)
以上代码将调用下面的代码
kotlin
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;
}
关键函数:Binder.allowBlocking(rawGetService(name))
typescript
public static IBinder allowBlocking(IBinder binder) {
try {
if (binder instanceof BinderProxy) {
((BinderProxy) binder).mWarnOnBlocking = false;
} else if (binder != null && binder.getInterfaceDescriptor() != null
&& binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
Log.w(TAG, "Unable to allow blocking on interface " + binder);
}
} catch (RemoteException ignored) {
}
return binder;
}
关键函数中 Binder.allowBlocking并没有什么实质性的有价值的代码,所以所有的核心代码在rawGetService中。
java
private static IBinder rawGetService(String name) throws RemoteException {
--------------- 省略
final IBinder binder = getIServiceManager().getService(name);
--------------- 省略
return binder;
}
这里的逻辑是,先通过getIServiceManager()获取到IServiceManager对象,然后再通过这个IServiceManager对象获取到一个IBinder。
注意,此处有两个IPC
- 获取到IServiceManager
- 通过IServiceManager获取到该name的Service的Binder的IPC
由于本文本文重在探索java到native的逻辑,我们且只看第一个。
关于第二个:源码中实现IServiceManager的类是ServiceManagerNative有兴趣的读者可以自己探索下,或者关注笔者后面的文章
ServiceManager.getIServiceManager()
csharp
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
到这,可以看到返回的其实是ServiceManagerNative.asInterface()的返回值。
对AIDL有所了解就知道,asInterface()的内容大概如下:
这个方法属于aidl接口的内部类 Stub。在同一进程中,就会直接返回Stub,如果在另一个进程中调用,就会返回将这个ibinder封装好的Proxy对象。对于上面的逻辑不太清楚的可以先学习前面的章节AIDL。于是,虽然没有看ServiceManagerNative的源码,但是其逻辑已经很清晰了。我们只需要关注IBinder的来源就可以了,也就是BinderInternal.getContextObject()。
BinderInternal.getContextObject()代码如下:
java
public static final native IBinder getContextObject();
至此,可以发现IBinder对象其实是从native层获取到的。
JNI层代码如下:
scss
android_util_Binder.android_os_BinderInternal_getContextObject()代码如下
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
这里先通过ProcessState获取到了一个native 层的IBinder强引用,也就是一个BpBinder。然后将这个native层的IBinder强引用传入javaObjectForIBinder()方法,最终封装成java层的IBinder然后返回。此处先不深究ProcessState的逻辑,整个native层的binder有自己的一整套的逻辑,后面的文章会继续探索。我们可以先稍微看下javaObjectForIBinder()的大概逻辑。android_util_Binder.javaObjectForIBinder()
kotlin
// If the argument is a JavaBBinder, return the Java object that was used to create it.
// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
// same IBinder, and the original BinderProxy is still alive, return the sameBinderProxy.
// 将一个BpBinder对象(这是native中的类型)转换成java中的类型
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
// N.B. This function is called from a @FastNative JNI method, so don't take locks
//around calls to Java code or block the calling thread for a long time for any
//reason.
if (val == NULL) return NULL;
//JavaBBinder返回true,其他类均返回flase
if (val->checkSubclass(&gBinderOffsets)) {
// It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = val;
// 核心代码:运用反射创建一个BinderProxy对象
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
if (env->ExceptionCheck()) {
// In the exception case, getInstance still took ownership of nativeData.
return NULL;
}
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
//如果object是刚刚新建出来的BinderProxy
if (actualNativeData == nativeData) {
//处理proxy计数
// Created a new Proxy
uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
// Multiple threads can get here, make sure only one of them gets to
// update the warn counter.
if (gProxiesWarned.compare_exchange_strong(numLastWarned,
numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed))
{
ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
}
}
} else {
delete nativeData;
}
return object; //object 是反射参数的java的 BinderProxy
}
上面的函数看起来复杂,其实功能就是将一个BpBinder对象(这是native中的类型)转换成java中的类型,中间采用了反射技术而已。
核心代码进行说明:
ini
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
gBinderProxyOffsets是什么?
ini
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass;
jmethodID mGetInstance;
jmethodID mSendDeathNotice;
// Object state.
//指向BinderProxyNativeData的指针
jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
} gBinderProxyOffsets;
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
...
jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
"(JJ)Landroid/os/BinderProxy;");
gBinderProxyOffsets.mSendDeathNotice =
GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
...
}
可以看到,gBinderProxyOffsets实际上是一个用来记录一些java中对应类、方法以及字段的结构体,用于从native层调用java层代码,而通过int_register_android_os_BinderProxy,我们知道,binderproxy_offsets_t中的mClass字段就是 BInderProxy,而mGetInstance 就是BInderProxy.java 中getInstance方法。因此核心代码创建的是一个BinderProxy对象。
具体的执行流程如下图所示:
第一大步:为了获取ServcieManager 的IServiceManager,首先要ServcieManager进程创建一个底层的Binder,所以会有android_os_BinderInternal_getContextObject也就是第2步,第2步会在ProcessState::self()中初始化Binder驱动,然后再执行第3步;
第二大步:上图中第3步会调用到第4步,在第4步getStrongProxyForHandle代码如下:
scss
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
//查找或建立handle对应的handle_entry
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. The
// attemptIncWeak() is safe because we know the BpBinder destructor will always
// call expungeHandle(), which acquires the same lock we are holding now.
// We need to do this because there is a race condition between someone
// releasing a reference on this BpBinder, and a new reference on its handle
// arriving from the driver.
IBinder* b = e->binder;
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
// Special case for context manager...
// The context manager is the only object for which we create
// a BpBinder proxy without already holding a reference.
// Perform a dummy transaction to ensure the context manager
// is registered before we create the first local reference
// to it (which will occur when creating the BpBinder).
// If a local reference is created for the BpBinder when the
// context manager is not present, the driver will fail to
// provide a reference to the context manager, but the
// driver API does not return status.
//
// Note that this is not race-free if the context manager
// dies while this code runs.
//
// TODO: add a driver API to wait for context manager, or
// stop special casing handle 0 for context manager and add
// a driver API to get a handle to the context manager with
// proper reference counting.
//当handle为ServiceManager的特殊情况
//需要确保在创建Binder引用之前,context manager已经被binder注册
//需要先确保邋ServcieManager活着
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
if (status == DEAD_OBJECT)
return nullptr;
}
//创建BpBinder并保存下来以便后面再次查找
b = BpBinder::create(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
其中会执行一个BpBinder::create(handle),此处会创建一个BpBinder对象,并且将BpBinder对象赋值给result对象并返回result,也就是返回BpBinder对象。这个BpBinder对象一路返回,最终在android_util_Binder.cpp中的android_os_BinderInternal_getContextObject函数中会执行下面的代码:
scss
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
也就是说b的值是BpBinder,然后BpBinder赋值给了javaObjectForIBinder作为参数。
第三大步:BpBinder需要返回给java层Client端使用,所以此时的封装就是将BpBinder封装成为Java层的BinderProxy对象。因此在Client端得到的IServiceManager 其实是BinderProxy类的子类的对象。
所以,BinderInternal.getContextObject(),返回的是一个层层封装的类的实例,具体来说,是Native层的BpBinder对象被封装成为BinderProxy对象并返回。
3. 出现了几个陌生的概念:BinderProxy,BpBinder,BBinder,IBinder
下面我们一一的介绍这些概念。
3.1 IBinder
arduino
// IBinder从Refbase继承而来,一提供强弱指针计数能力
class IBinder : public virtual RefBase
{
public:
enum {
FIRST_CALL_TRANSACTION = 0x00000001,
LAST_CALL_TRANSACTION = 0x00ffffff,
PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'),
DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'),
INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'),
// Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001
};
IBinder();
// 根据descriptor查询相应的IInterface对象
virtual sp<IInterface> queryLocalInterface(const String16& descriptor);
// 获取descriptor描述符
virtual const String16& getInterfaceDescriptor() const = 0;
virtual bool isBinderAlive() const = 0;
virtual status_t pingBinder() = 0;
virtual status_t dump(int fd, const Vector<String16>& args) = 0;
// transact binder通信函数
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0) = 0;
// 死亡通知相应类
class DeathRecipient : public virtual RefBase
{
public:
virtual void binderDied(const wp<IBinder>& who) = 0;
};
// 如其名,用于注册Binder用的
virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0) = 0;
// 撤销用之前注册的死亡通知函数
virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL) = 0;
virtual bool checkSubclass(const void* subclassID) const;
typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);
virtual void attachObject( const void* objectID,
void* object,
void* cleanupCookie,
object_cleanup_func func) = 0;
virtual void* findObject(const void* objectID) const = 0;
virtual void detachObject(const void* objectID) = 0;
// 返回服务端的binder引用
virtual BBinder* localBinder();
// 放回客户端的binder引用
virtual BpBinder* remoteBinder();
protected:
virtual ~IBinder();
private:
};
BpBinder的构造函数
scss
BpBinder::BpBinder(int32_t handle)
: mHandle(handle) // 将传入的handle值保存到mHandle成员变量里
, mAlive(1) // mAlive设置为1
, mObitsSent(0)
, mObituaries(NULL)
{
ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
IPCThreadState::self()->incWeakHandle(handle);
}
首先调用extendObjectLifetime将对象改为弱引用控制,通过IPCThreadState的incWeakHandle增加Binder Service的如引用计数值。IncWeakHandle如下:
void IPCThreadState::incWeakHandle(int32_t handle)
{
LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
mOut.writeInt32(BC_INCREFS);
mOut.writeInt32(handle);
}
这一步只是将BC_INCREFS请求写到mOut中,还没有发送出去。
除了incWeakHandle函数外还有decWeakHandle,incStrongHandle和decStrongHandle与Binder协议中的其他命令对应起来。这些细节我们就先不分析了。
另外,transact函数是核心,因为,Client是需要通过transact将请求传递给Binder驱动的,所以transact是BpBinder的核心函数之一。
3.3 BBinder
arduino
class BBinder : public IBinder
{
public:
BBinder();
virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0);
virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL);
virtual void attachObject( const void* objectID,
void* object,
void* cleanupCookie,
object_cleanup_func func);
virtual void* findObject(const void* objectID) const;
virtual void detachObject(const void* objectID);
virtual BBinder* localBinder();
protected:
virtual ~BBinder();
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
private:
BBinder(const BBinder& o);
BBinder& operator=(const BBinder& o);
class Extras;
atomic_uintptr_t mExtras; // should be atomic<Extras *>
void* mReserved0;
};
其中,isBinderAlive函数只是返回true,这很好理解,因为BBinder代表的是Binder通信中的服务端,服务端是否存活,服务端自己当然是知道的。同时linkToDeath和unlinkToDeath这两个函数都只是返回INVALID_OPERATION,表明这两个函数在服务端是不需要做什么的,毕竟这两个函数是用来注册死亡通知用的。
由于是服务端,所以是Client端向服务端发起请求,因此它的核心也有一个transact函数,只是transact的核心却是onTransact函数,只是在onTransact没有什么实际的实现,最终会由子类去具体实现具体的功能。
3.4 JavaBBinder
IBinder是BBinder的父类,BBinder是JavaBBinder的父类。
java层直接与native层交互的对象有两个------Binder对象与BinderProxy对象。
Binder对应"Binder在本进程"的场景,BinderProxy对应"Binder在其他进程"的场景。
native层javaBBinder与java层的Binder一一对应。
native层的BinderProxyNativeData与java层的BinderProxy一一对应。
在native层,gBinderProxyOffsets(binderproxy_offsets_t)存储了java层binderProxy的对象与需要调用的方法和属性。gBinderOffsets(binderproxy_offsets_t)存储了java层binder的对象与需要调用的方法和属性。
ibinderForJavaObject负责通过java的Binder或者BinderProxy对象,找到并返回native层的IBinder对象。
javaObjectForIBinder通过native层的IBinder对象,找到或者封装成java对象返回。
今日分享到此结束,对你有帮助的话,点个赞再走呗,如遇侵权联系删除
关注公众号:Android老皮解锁 《Android十大板块文档》 ,让学习更贴近未来实战。已形成PDF版
内容如下:
1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路