IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Binder java端的调用流程 -> 正文阅读

[移动开发]Android Binder java端的调用流程

本篇从ServiceManager.addService中开始讲起

Android Binder getService(java)源码分析(二)_we1less的博客-CSDN博客关于native层在java端的代理ServiceManagerProxy对象已经在这篇阐述过了

addService

????????路径? frameworks/base/core/java/android/os/ServiceManagerNative.java

????????data.writeStrongBinder(service);

public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

writeStrongBinder

????????路径? frameworks/base/core/java/android/os/Parcel.java

? ? ? ? java层的Parcel 主要是调用native层的Parcel

public final void writeStrongBinder(IBinder val) {
        nativeWriteStrongBinder(mNativePtr, val);
    }

?nativeWriteStrongBinder

? ? ? ? 路径??frameworks/base/core/jni/android_os_Parcel.cpp

? ? ? ? native层的Parcel的writeStrongBinder入参要是sp<IBinder>& val

????????jobject object类型转换主要靠ibinderForJavaObject

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

ibinderForJavaObject

? ? ? ? 路径??frameworks/base/core/jni/android_util_Binder.cpp

? ? ? ? 将java层的对象转换为Ibinder类型????????

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    if (obj == NULL) return NULL;
    //判断传递进来的对象是否是gBinderOffsets.mClass的子类
    //可以看出gBinderOffsets.mClass是java的Binder类
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            //从obj中获取gBinderOffsets.mObject成员属性并强转成JavaBBinderHolder类型
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL;
    }

    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
    }

    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
    return NULL;
}
const char* const kBinderPathName = "android/os/Binder";

static int int_register_android_os_Binder(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, kBinderPathName);

    gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    //...
}

gBinderOffsets.mObject?

? ? ? ? 路径??frameworks/base/core/jni/android_util_Binder.cpp

???????gBinderOffsets.mObject是何时被赋值成JavaBBinderHolder?

? ? ? ? 当init的时候直接new出来被设置进去的? 同样的这个方法也是一个jni方法

static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
    JavaBBinderHolder* jbh = new JavaBBinderHolder();
    if (jbh == NULL) {
        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
        return;
    }
    ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
    jbh->incStrong((void*)android_os_Binder_init);
    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}

{ "init", "()V", (void*)android_os_Binder_init },

?init

? ? ? ? 路径??frameworks/base/core/java/android/os/Binder.java

? ? ? ? 很显然是当初始化java层子类service的构造器的时候初始化的

public Binder() {
        init();
        ...
    }

jbh->get(env, obj)

? ? ? ? 路径??frameworks/base/core/jni/android_util_Binder.cpp

? ? ? ? 直接返回new的一个JavaBBinder

sp<JavaBBinder> get(JNIEnv* env, jobject obj)
    {
        AutoMutex _l(mLock);
        sp<JavaBBinder> b = mBinder.promote();
        if (b == NULL) {
            b = new JavaBBinder(env, obj);
            mBinder = b;
            ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
        }

        return b;
    }

?JavaBBinder

? ? ? ? 路径???frameworks/base/core/jni/android_util_Binder.cpp

? ? ? ? 将传递进来的对象赋值给mObject

JavaBBinder(JNIEnv* env, jobject object)
        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    {
        ALOGV("Creating JavaBBinder %p\n", this);
        android_atomic_inc(&gNumLocalRefs);
        incRefsCreated(env);
    }

? ? ? ? ?这样就可以用传递进来的mObject对象回调java层的onTransact方法

? ? ? ? 调用mObjectgBinderOffsets.mExecTransact方法 就是调用Binder.javaexecTransact

 virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {
        ...
        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);

execTransact

????????路径? frameworks/base/core/java/android/os/Binder.java?

? ? ? ? 因为mObject对象是继承Binder对象所以调用的是父类Binder对象的execTransact方法

? ? ? ? 最后调用到自身的onTransact方法

private boolean execTransact(int code, long dataObj, long replyObj,
            int flags) {
        ...
            res = onTransact(code, data, reply, flags);
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-23 12:37:23  更:2021-10-23 12:38:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:28:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码