Android Framework如何实现Binder

作者:Arthas0v0 时间:2021-12-09 03:54:20 

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
    */
   @UnsupportedAppUsage
   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;
   }
   @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变量来实现的。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调用。

@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;
}

就是调用的传入的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(@Nullable 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来实现。

来源:https://juejin.cn/post/7142870282468851749

标签:Android,Framework,Binder
0
投稿

猜你喜欢

  • C# WinForm控件对透明图片重叠时出现图片不透明的简单解决方法

    2021-06-06 04:59:48
  • SpringBoot程序的打包与运行的实现

    2023-11-29 15:51:27
  • 详解Android StrictMode严格模式的使用方法

    2023-09-14 17:03:39
  • 分享几个Java工作中实用的代码优化技巧

    2023-11-28 12:04:50
  • JavaWeb实现用户登录与注册功能

    2022-08-30 17:23:48
  • Java日常练习题,每天进步一点点(41)

    2023-05-18 18:10:02
  • java数据结构之希尔排序

    2023-11-08 18:16:18
  • C#中字符串的加密的源码

    2023-09-14 22:35:34
  • SpringCloud之分布式配置中心Spring Cloud Config高可用配置实例代码

    2021-06-23 16:48:08
  • c#遍历System.drawing.Color下面的所有颜色以及名称以查看

    2022-05-12 06:33:19
  • Java 获取网络302重定向URL的方法

    2022-03-25 15:19:46
  • Android TextWatcher监控EditText中的输入内容并限制其个数

    2022-08-18 13:27:41
  • C#中WPF内存回收与释放LierdaCracker的实现

    2022-11-13 00:15:44
  • C#实现随机数产生类实例

    2021-11-16 15:46:49
  • ElasticSearch添加索引代码实例解析

    2023-11-21 03:41:04
  • C#实现加密与解密详解

    2023-08-11 16:54:42
  • Java毕业设计实战之药店信息管理系统的实现

    2022-03-07 11:55:37
  • C#实现文件上传及文件下载功能实例代码

    2022-12-13 23:57:23
  • Android zygote启动流程详解

    2023-09-13 07:44:12
  • flutter material widget组件之信息展示组件使用详解

    2023-06-22 08:45:35
  • asp之家 软件编程 m.aspxhome.com