Android Binder javajni源码分析

Posted we1less

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Binder javajni源码分析相关的知识,希望对你有一定的参考价值。

android开发中java端调用getSystemService(xxx); 

getSystemService(Context.CONNECTIVITY_SERVICE);

Activity.java   路径 frameworks/base/core/java/android/app/Activity.java 

        如果获取的Service不是代码中所示的,那么就调用父类ContextThemeWrappergetSystemService

public class Activity extends ContextThemeWrapper

...

@Override
    public Object getSystemService(@ServiceName @NonNull String name) {
        if (getBaseContext() == null) {
            throw new IllegalStateException(
                    "System services not available to Activities before onCreate()");
        }

        if (WINDOW_SERVICE.equals(name)) {
            return mWindowManager;
        } else if (SEARCH_SERVICE.equals(name)) {
            ensureSearchManager();
            return mSearchManager;
        }
        return super.getSystemService(name);
    }

ContextThemeWrapper.java

        路径 frameworks/base/core/java/android/view/ContextThemeWrapper.java

        getBaseContext() 返回的实际是Context的子类,ContextImpl

@Override
public Object getSystemService(String name) {
    if (LAYOUT_INFLATER_SERVICE.equals(name)) {
        if (mInflater == null) {
            mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
        }
        return mInflater;
    }
    return getBaseContext().getSystemService(name);
}

ContextImpl.java  路径 frameworks/base/core/java/android/app/ContextImpl.java

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}

SystemServiceRegistry.java 

路径  frameworks/base/core/java/android/app/SystemServiceRegistry.java 

这里面存在的静态代码块就是调用的ServiceManager.getServiceOrThrow获取系统binder对象的

IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);

final class SystemServiceRegistry {

    private static final String TAG = "SystemServiceRegistry";

    ......

    private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new HashMap<String, ServiceFetcher<?>>();

    private static int sServiceCacheSize;

    // Not instantiable.
    private SystemServiceRegistry() { }

    static {

        ......

        registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class,
                new StaticApplicationContextServiceFetcher<ConnectivityManager>() {
            @Override
            public ConnectivityManager createService(Context context) throws ServiceNotFoundException {
                IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
                IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
                return new ConnectivityManager(context, service);
            }});

        ......    
    }

    public static Object getSystemService(ContextImpl ctx, String name) {
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;
    }

    private static <T> void registerService(String serviceName, Class<T> serviceClass,
            ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }
    
    static abstract interface ServiceFetcher<T> {
        T getService(ContextImpl ctx);
    }

    ......
}

ServiceManager.java   路径 frameworks/base/core/java/android/os/ServiceManager.java 

        调用本类中的getService方法

public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
    final IBinder binder = getService(name);
    if (binder != null) {
        return binder;
    } else {
        throw new ServiceNotFoundException(name);
    }
}

ServiceManager.java  路径frameworks/base/core/java/android/os/ServiceManager.java

        这里面主要是调用了getIServiceManager().getService(name)

public static IBinder getService(String name) {
    try {
        IBinder service = sCache.get(name);
        if (service != null) {
            return service;
        } else {
            return Binder.allowBlocking(getIServiceManager().getService(name));
        }
    } catch (RemoteException e) {
        Log.e(TAG, "error in getService", e);
    }
    return null;
}

 getIServiceManager()  

        Binder.allowBlocking(BinderInternal.getContextObject())  这块应该是返回ServiceManagerIBinder对象用来进行ServiceManager的跨进程通信

        BinderInternal.getContextObject() 最终返回的就是android/os/BinderProxy对象

private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

BinderInternal.getContextObject() 

        路径 frameworks/base/core/java/com/android/internal/os/BinderInternal.java

        这是一个native方法,jni方法那就根据包名类名找到对应的jni方法

        其实这里最终返回的就是android/os/BinderProxy对象

public static final native IBinder getContextObject();

android_os_BinderInternal_getContextObject

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

        javaObjectForIBinder将native层的IBinder对象转换为java层的IBinder对象

        sp<IBinder> b = new BpBinder(0);        

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    //相当于 sp<IBinder> b = new BpBinder(0);
    return javaObjectForIBinder(env, b);
}

ProcessState::self()->getContextObject(NULL)

        路径 frameworks/native/libs/binder/ProcessState.cpp

        getStrongProxyForHandle Handle等于0代表获取ServiceManager

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

getStrongProxyForHandle

        这里面调用了lookupHandleLocked构造了一个handle_entry,然后ping了一下ServiceManager,最后new了一个BpBinder返回

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }

            b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

lookupHandleLocked

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = NULL;
        e.refs = NULL;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return NULL;
    }
    return &mHandleToObject.editItemAt(handle);
}

回到jni的代码javaObjectForIBinder

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

        这个函数主要的作用就是将native的对象转化为java的对象,省略的部分就是函数的检查部分,接下来调用env的创建对象函数gBinderProxyOffsets.mClass  android/os/BinderProxy的java字节码文件,并将上文中创建好的 sp<IBinder> b = new BpBinder(0);传递给BinderProxymObject对象

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    ...
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        ...
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        ...
        //这个native对象需要保留一个对代理的弱引用,这样就可以在同一个代理仍然处于活动状态时检索它。
        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);
        ...
    }

    return object;
}

gBinderProxyOffsets

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

        android/os/BinderProxy的java类这里面获取了关于这个类的构造器和成员变量                 

const char* const kBinderProxyPathName = "android/os/BinderProxy";


//结构体
static struct binderproxy_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mConstructor;
    jmethodID mSendDeathNotice;

    // Object state.
    jfieldID mObject;
    jfieldID mSelf;
    jfieldID mOrgue;

} gBinderProxyOffsets;


static int int_register_android_os_BinderProxy(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, "java/lang/Error");
    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

    clazz = FindClassOrDie(env, kBinderProxyPathName);
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
    gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
            "(Landroid/os/IBinder$DeathRecipient;)V");

    gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
                                                "Ljava/lang/ref/WeakReference;");
    gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");

    clazz = FindClassOrDie(env, "java/lang/Class");
    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

    return RegisterMethodsOrDie(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

以上是关于Android Binder javajni源码分析的主要内容,如果未能解决你的问题,请参考以下文章

Android Framework实战开发-binder通信java及jni部分源码分析

Android Framework实战开发-binder通信java及jni部分源码分析

Binder 机制分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 )

BInder

BInder

Android源码解析RPC系列(一)---Binder原理