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設置了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對象并把傳進來的binder設置給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對象?;氐絡avaObjectForIBinder中獲取到BinderProxy對象之后調(diào)用了getBPNativeData,這個方法獲取了BinderProxy對象的BinderProxyNativeData地址通過這個地址和前面創(chuàng)建的nativeData地址判斷mGetInstance獲取的到的對象是新創(chuàng)建的還是緩存里面的。如果不是緩存里的話就更新維護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對應的ServiceManagerNative,同時也找到了Bpbinder對應的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。其實這里用了一個延遲初始化,當這個Binder對象需要作為本地Binder對象傳遞的時候會使用Parcel的writeStrongBinder來進行封裝。它也是一個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)都一一有了對應,具體通訊的功能都是通過jni對應到了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-03
A10_DatePicker的對話框設置(使用OnDateSetListener監(jiān)聽器)
本文主要彌補A07_TimePicker & DatePicker & AnalogClock & DigitalClock 的設置,具體實現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-06-06
Android開發(fā)之開發(fā)者頭條APP(三)實現(xiàn)首頁
這篇文章主要介紹了Android開發(fā)之開發(fā)者頭條APP(三)實現(xiàn)首頁的相關(guān)資料,需要的朋友可以參考下2016-04-04

