目录
- Framework如何实现Binder
- ServiceManager
- 小结
- Binder结构
Framework如何实现Binder
为了日常的使用framework层同样实现了一套binder的接口。可以肯定的是framework使用jni调用的是native的binder接口,在native层Binder结构通过BBinder,BpBinder和ServiceManager来实现。
ServiceManager
framework层的ServiceManager的路径在frameworks/base/core/java/android/os/ServiceManager.java
。从ServiceManager最重要的两个功能addService和getService来看下framework层的实现。
public static void addService(String name, IBinder service, boolean allowIsolated, | |
int dumpPriority) { | |
try { | |
getIServiceManager().addService(name, service, allowIsolated, dumpPriority); | |
} catch (RemoteException e) { | |
Log.e(TAG, "error in addService", e); | |
} | |
} | |
private static IServiceManager getIServiceManager() { | |
if (sServiceManager != null) { | |
return sServiceManager; | |
} | |
| |
// Find the service manager | |
sServiceManager = ServiceManagerNative | |
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); | |
return sServiceManager; | |
} | |
public final class ServiceManagerNative { | |
private ServiceManagerNative() {} | |
| |
/** | |
* Cast a Binder object into a service manager interface, generating | |
* a proxy if needed. | |
* | |
* TODO: delete this method and have clients use | |
* IServiceManager.Stub.asInterface instead | |
*/ | |
public static IServiceManager asInterface(IBinder obj) { | |
if (obj == null) { | |
return null; | |
} | |
// ServiceManager is never local | |
return new ServiceManagerProxy(obj); | |
} | |
} |
getIServiceManager()获取的实际是一个ServiceManagerProxy对象。构造函数的参数Binder.allowBlocking(BinderInternal.getContextObject())
//frameworks/base/core/java/android/os/Binder.java | |
public static IBinder allowBlocking(IBinder binder) {//判断了下是不是本地binder设置了mWarnOnBlocking,就返回了,所以还是传入的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; | |
} | |
//frameworks/base/core/java/com/android/internal/os/BinderInternal.java | |
public static final native IBinder getContextObject(); |
是个native方法
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) | |
{ | |
sp<IBinder> b = ProcessState::self()->getContextObject(NULL); | |
return javaObjectForIBinder(env, b); | |
} |
回到了熟悉的native层,ProcessState::self()->getContextObject(NULL)获取了ServiceManager的代理Bpbinder(0),调用javaObjectForIBinder()封装成java对象返回。
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) | |
{ | |
if (val == NULL) return NULL; | |
| |
if (val->checkSubclass(&gBinderOffsets)) {//如果是一个JavaBBinder对象直接返回 | |
// 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();//创建了一个BinderProxyNativeData对象并把传进来的binder设置给mObject | |
nativeData->mOrgue = new DeathRecipientList; | |
nativeData->mObject = val; | |
| |
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass, | |
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());//调用了gBinderProxyOffsets.mGetInstance方法创建了一个binderproxy | |
if (env->ExceptionCheck()) { | |
// In the exception case, getInstance still took ownership of nativeData. | |
return NULL; | |
} | |
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object); | |
if (actualNativeData == nativeData) {// | |
// Created a new Proxy | |
uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);//memory_order_relaxed类似volatile的功能 | |
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; | |
} |
gBinderProxyOffsets.mGetInstance这个方法的定义在frameworks/base/core/jni/android_util_Binder.cpp
中
gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance", | |
"(JJ)Landroid/os/BinderProxy;");//就是BinderProxy的getInstance方法 | |
//frameworks/base/core/java/android/os/BinderProxy.java | |
private static BinderProxy getInstance(long nativeData, long iBinder) { | |
BinderProxy result; | |
synchronized (sProxyMap) { | |
try { | |
result = sProxyMap.get(iBinder);//查看这个iBinder有没有在缓存中 | |
if (result != null) { | |
return result; | |
} | |
result = new BinderProxy(nativeData); | |
} catch (Throwable e) { | |
// We're throwing an exception (probably OOME); don't drop nativeData. | |
NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer, | |
nativeData); | |
throw e; | |
} | |
NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData); | |
// The registry now owns nativeData, even if registration threw an exception. | |
sProxyMap.set(iBinder, result); | |
} | |
return result; | |
} |
所以gBinderProxyOffsets.mGetInstance就是通过BinderProxyNativeData和BpBinder(0)拿到了BinderProxy对象。回到javaObjectForIBinder中获取到BinderProxy对象之后调用了getBPNativeData,这个方法获取了BinderProxy对象的BinderProxyNativeData地址通过这个地址和前面创建的nativeData地址判断mGetInstance获取的到的对象是新创建的还是缓存里面的。如果不是缓存里的话就更新维护BinderProxy的一些值。
class ServiceManagerProxy implements IServiceManager { | |
public ServiceManagerProxy(IBinder remote) {//remote就是BinderProxy | |
mRemote = remote; | |
mServiceManager = IServiceManager.Stub.asInterface(remote); | |
} | |
public IBinder asBinder() { | |
return mRemote; | |
} | |
public IBinder getService(String name) throws RemoteException { | |
// Same as checkService (old versions of servicemanager had both methods). | |
return mServiceManager.checkService(name); | |
} | |
public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) | |
throws RemoteException { | |
mServiceManager.addService(name, service, allowIsolated, dumpPriority); | |
} | |
private IBinder mRemote; | |
private IServiceManager mServiceManager; | |
} |
addService和getService都是通过mServiceManager变量来实现的。IServiceManager是一个aidl文件编译之后生成java代码。
public static android.os.IServiceManager asInterface(android.os.IBinder obj) | |
{ | |
if ((obj == null)) { | |
return null; | |
} | |
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); | |
if (((iin != null) && (iin instanceof android.os.IServiceManager))) { | |
return ((android.os.IServiceManager) iin); | |
} | |
return new android.os.IServiceManager.Stub.Proxy(obj); | |
} |
IServiceManager.Stub.asInterface返回的就是android.os.IServiceManager.Stub.Proxy类型看下getService调用。
public android.os.IBinder getService(java.lang.String name) throws android.os.RemoteException | |
{ | |
android.os.Parcel _data = android.os.Parcel.obtain(); | |
android.os.Parcel _reply = android.os.Parcel.obtain(); | |
android.os.IBinder _result; | |
try { | |
_data.writeInterfaceToken(DESCRIPTOR); | |
_data.writeString(name); | |
boolean _status = mRemote.transact(Stub.TRANSACTION_getService, _data, _reply, 0); | |
_reply.readException(); | |
_result = _reply.readStrongBinder(); | |
} | |
finally { | |
_reply.recycle(); | |
_data.recycle(); | |
} | |
return _result; | |
} |
就是调用的传入的BinderProxy的transact方法:
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { | |
........ | |
final boolean result = transactNative(code, data, reply, flags);//去除前面的异常处理和oneway判断之后,真正的调用就是这一行 | |
| |
if (reply != null && !warnOnBlocking) { | |
reply.addFlags(Parcel.FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT); | |
} | |
| |
return result; | |
} |
这是一个jni方法,它的实现也在frameworks/base/core/jni/android_util_Binder.cpp
中
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, | |
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException | |
{ | |
................ | |
Parcel* data = parcelForJavaObject(env, dataObj); | |
Parcel* reply = parcelForJavaObject(env, replyObj); | |
IBinder* target = getBPNativeData(env, obj)->mObject.get();//拿到前面存储的BinderProxyNativeData | |
//printf("Transact from Java code to %p sending: ", target); data->print(); | |
status_t err = target->transact(code, *data, reply, flags);//调用transact | |
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); | |
.................. | |
return JNI_FALSE; | |
} |
getBPNativeData前面已经分析过了就是拿到了BinderProxyNativeData,mObject就是前面初始化传入的Bpbinder(0),最后就调用到了的transact方法。到这里之后就是走的native层的binder调用了BpBinder->transact() ->IPCThreadState::self()->transact() ->IPCThreadState::writeTransactionData->IPCThreadState::waitForResponse->BinderCallback-> IPCThreadState::getAndExecuteCommand->IPCThreadState::executeCommand->BnServiceManager::onTransact。
小结
framework层ServiceManager的实现原理就解析到这了,总结一下通过jni方法创建了ServiceManager的BinderProxy对象,层层封装成了ServiceManagerNative。后续的调用实际都是调用的native层的Bpbinder的方法。
Binder结构
现在分析了和native层ServiceManager对应的ServiceManagerNative,同时也找到了Bpbinder对应的BinderProxy,现在就剩下了BBbinder,在framework中就是Binder类,看下Binder的构造函数。
public Binder( { String descriptor) | |
mObject = getNativeBBinderHolder();//创建了一个JavaBBinderHolder对象,返回了指向这个对象的指针mObject | |
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);//管理与Java对象有关的native内存。 | |
| |
if (FIND_POTENTIAL_LEAKS) { | |
final Class<? extends Binder> klass = getClass(); | |
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && | |
(klass.getModifiers() & Modifier.STATIC) == 0) { | |
Log.w(TAG, "The following Binder class should be static or leaks might occur: " + | |
klass.getCanonicalName()); | |
} | |
} | |
mDescriptor = descriptor; | |
} |
getNativeBBinderHolder是个native方法,实现还是在frameworks/base/core/jni/android_util_Binder.cpp
中
static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz) | |
{ | |
JavaBBinderHolder* jbh = new JavaBBinderHolder(); | |
return (jlong) jbh; | |
} |
到这里好像只是创建了一个JavaBBinderHolder和Binder对象组合了起来,没有看到BBinder。其实这里用了一个延迟初始化,当这个Binder对象需要作为本地Binder对象传递的时候会使用Parcel的writeStrongBinder来进行封装。它也是一个native方法,具体实现在frameworks/base/core/jni/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); | |
} | |
} | |
} | |
//frameworks/base/core/jni/android_util_Binder.cpp | |
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) | |
{ | |
if (obj == NULL) return NULL; | |
| |
// Instance of Binder? | |
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { | |
JavaBBinderHolder* jbh = (JavaBBinderHolder*) | |
env->GetLongField(obj, gBinderOffsets.mObject); | |
return jbh->get(env, obj);//如果是Binder对象调用JavaBBinderHolder的get方法。 | |
} | |
| |
// Instance of BinderProxy? | |
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { | |
return getBPNativeData(env, obj)->mObject; | |
} | |
| |
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); | |
return NULL; | |
} |
关键就在JavaBBinderHolder的get方法了:
//frameworks/base/core/jni/android_util_Binder.cpp | |
sp<JavaBBinder> get(JNIEnv* env, jobject obj) | |
{ | |
AutoMutex _l(mLock); | |
sp<JavaBBinder> b = mBinder.promote(); | |
if (b == NULL) { | |
b = new JavaBBinder(env, obj);//创建JavaBBinder对象 | |
if (mVintf) { | |
::android::internal::Stability::markVintf(b.get()); | |
} | |
if (mExtension != nullptr) { | |
b.get()->setExtension(mExtension); | |
} | |
mBinder = b; | |
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n", | |
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount()); | |
} | |
| |
return b; | |
} | |
class JavaBBinder : public BBinder | |
{ | |
public: | |
JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object) | |
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)) | |
{ | |
ALOGV("Creating JavaBBinder %p\n", this); | |
gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed); | |
gcIfManyNewRefs(env); | |
} | |
| |
bool checkSubclass(const void* subclassID) const | |
{ | |
return subclassID == &gBinderOffsets; | |
} | |
| |
jobject object() const | |
{ | |
return mObject; | |
} |
JavaBBinder就是继承了BBinder对象,到这里Binder的Java对象和BBinder也关联了起来。而Binder结构的三个组成部分client(Binder),service(BinderProxy),ServiceManagert(ServiceManagerNative)都一一有了对应,具体通讯的功能都是通过jni对应到了native层的binder架构BBinder,BpBinder,ServiceManager来实现。