Android?Framework如何實現(xiàn)Binder
Framework如何實現(xiàn)Binder
為了日常的使用framework層同樣實現(xiàn)了一套binder的接口??梢钥隙ǖ氖莊ramework使用jni調(diào)用的是native的binder接口,在native層Binder結(jié)構(gòu)通過BBinder,BpBinder和ServiceManager來實現(xiàn)。
ServiceManager
framework層的ServiceManager的路徑在frameworks/base/core/java/android/os/ServiceManager.java
。從ServiceManager最重要的兩個功能addService和getService來看下framework層的實現(xiàn)。
? ?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 ? ? */ ? ?@UnsupportedAppUsage ? ?public static IServiceManager asInterface(IBinder obj) { ? ? ? ?if (obj == null) { ? ? ? ? ? ?return null; ? ? ? } ? ? ? ?// ServiceManager is never local ? ? ? ?return new ServiceManagerProxy(obj); ? } }
getIServiceManager()獲取的實際是一個ServiceManagerProxy對象。構(gòu)造函數(shù)的參數(shù)Binder.allowBlocking(BinderInternal.getContextObject())
//frameworks/base/core/java/android/os/Binder.java public static IBinder allowBlocking(IBinder binder) {//判斷了下是不是本地binder設(shè)置了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),調(diào)用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();//創(chuàng)建了一個BinderProxyNativeData對象并把傳進(jìn)來的binder設(shè)置給mObject ? ?nativeData->mOrgue = new DeathRecipientList; ? ?nativeData->mObject = val; ? ? ?jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass, ? ? ? ? ? ?gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());//調(diào)用了gBinderProxyOffsets.mGetInstance方法創(chuàng)建了一個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對象。回到j(luò)avaObjectForIBinder中獲取到BinderProxy對象之后調(diào)用了getBPNativeData,這個方法獲取了BinderProxy對象的BinderProxyNativeData地址通過這個地址和前面創(chuàng)建的nativeData地址判斷mGetInstance獲取的到的對象是新創(chuàng)建的還是緩存里面的。如果不是緩存里的話就更新維護(hù)BinderProxy的一些值。
class ServiceManagerProxy implements IServiceManager { ? ?public ServiceManagerProxy(IBinder remote) {//remote就是BinderProxy ? ? ? ?mRemote = remote; ? ? ? ?mServiceManager = IServiceManager.Stub.asInterface(remote); ? } ? ?public IBinder asBinder() { ? ? ? ?return mRemote; ? } ? ?@UnsupportedAppUsage ? ?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); ? } ? ?@UnsupportedAppUsage ? ?private IBinder mRemote; ? ?private IServiceManager mServiceManager; }
addService和getService都是通過mServiceManager變量來實現(xiàn)的。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調(diào)用。
@Override 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; }
就是調(diào)用的傳入的BinderProxy的transact方法:
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { ........ ? ? ? ? ? ?final boolean result = transactNative(code, data, reply, flags);//去除前面的異常處理和oneway判斷之后,真正的調(diào)用就是這一行 ? ? ? ? ? ? ?if (reply != null && !warnOnBlocking) { ? ? ? ? ? ? ? ?reply.addFlags(Parcel.FLAG_IS_REPLY_FROM_BLOCKING_ALLOWED_OBJECT); ? ? ? ? ? } ? ? ? ? ? ? ?return result; ? }
這是一個jni方法,它的實現(xiàn)也在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);//調(diào)用transact ? ?//if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); .................. ? ?return JNI_FALSE; }
getBPNativeData前面已經(jīng)分析過了就是拿到了BinderProxyNativeData,mObject就是前面初始化傳入的Bpbinder(0),最后就調(diào)用到了的transact方法。到這里之后就是走的native層的binder調(diào)用了BpBinder->transact() ->IPCThreadState::self()->transact() ->IPCThreadState::writeTransactionData->IPCThreadState::waitForResponse->BinderCallback-> IPCThreadState::getAndExecuteCommand->IPCThreadState::executeCommand->BnServiceManager::onTransact。
小結(jié)
framework層ServiceManager的實現(xiàn)原理就解析到這了,總結(jié)一下通過jni方法創(chuàng)建了ServiceManager的BinderProxy對象,層層封裝成了ServiceManagerNative。后續(xù)的調(diào)用實際都是調(diào)用的native層的Bpbinder的方法。
Binder結(jié)構(gòu)
現(xiàn)在分析了和native層ServiceManager對應(yīng)的ServiceManagerNative,同時也找到了Bpbinder對應(yīng)的BinderProxy,現(xiàn)在就剩下了BBbinder,在framework中就是Binder類,看下Binder的構(gòu)造函數(shù)。
public Binder(@Nullable String descriptor) { ? ? ? ?mObject = getNativeBBinderHolder();//創(chuàng)建了一個JavaBBinderHolder對象,返回了指向這個對象的指針mObject ? ? ? ?NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);//管理與Java對象有關(guān)的native內(nèi)存。 ? ? ? ? ?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方法,實現(xiàn)還是在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; }
到這里好像只是創(chuàng)建了一個JavaBBinderHolder和Binder對象組合了起來,沒有看到BBinder。其實這里用了一個延遲初始化,當(dāng)這個Binder對象需要作為本地Binder對象傳遞的時候會使用Parcel的writeStrongBinder來進(jìn)行封裝。它也是一個native方法,具體實現(xiàn)在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對象調(diào)用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; }
關(guān)鍵就在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);//創(chuàng)建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也關(guān)聯(lián)了起來。而Binder結(jié)構(gòu)的三個組成部分client(Binder),service(BinderProxy),ServiceManagert(ServiceManagerNative)都一一有了對應(yīng),具體通訊的功能都是通過jni對應(yīng)到了native層的binder架構(gòu)BBinder,BpBinder,ServiceManager來實現(xiàn)。
到此這篇關(guān)于Android Framework如何實現(xiàn)Binder的文章就介紹到這了,更多相關(guān)Android 實現(xiàn)Binder內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android 自定義密碼輸入框?qū)崿F(xiàn)代碼
最近做個項目自定義密碼輸入框功能,下面小編把實現(xiàn)思路分享到腳本之家平臺,需要的朋友參考下吧2018-03-03A10_DatePicker的對話框設(shè)置(使用OnDateSetListener監(jiān)聽器)
本文主要彌補A07_TimePicker & DatePicker & AnalogClock & DigitalClock 的設(shè)置,具體實現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-06-06Android開發(fā)之開發(fā)者頭條APP(三)實現(xiàn)首頁
這篇文章主要介紹了Android開發(fā)之開發(fā)者頭條APP(三)實現(xiàn)首頁的相關(guān)資料,需要的朋友可以參考下2016-04-04