안 드 로 이 드 소스 3

56747 단어 android
Java 계층 Binder 프레임 워 크 초기 화
Android 시스템 에서 자바 초창기 에 시스템 은 JNI 함 수 를 미리 등록 합 니 다.그 중에서 자바 Binder 와 Native Binder 의 상호작용 관 계 를 구축 하 는 함수 가 있 습 니 다.rameworks\base\core\jni\\androidutil_Binder.cpp
int register_android_os_Binder(JNIEnv* env)
{
//   Java Binder  Native    
    if (int_register_android_os_Binder(env) < 0)
        return -1;
         //   Java BinderInternal  Native    
    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;
         //   Java BinderProxy  Native    
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;
        //   Java Parcel  Native    
    if (int_register_android_os_Parcel(env) < 0)
        return -1;
    return 0;
}

Binder 클래스 초기 화
static int int_register_android_os_Binder(JNIEnv* env)
{
    jclass clazz;
 //kBinderPathName Java  Binder      ,“android/os/Binder“
    clazz = env->FindClass(kBinderPathName);
    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
  /*

  gBinderOffSets        ,     Binder     JNI       ,

       execTranscat methodID,Binder    mObject fildID

  */
    gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    gBinderOffsets.mExecTransact
        = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
    assert(gBinderOffsets.mExecTransact);

    gBinderOffsets.mObject
        = env->GetFieldID(clazz, "mObject", "I");
    assert(gBinderOffsets.mObject);
//  Binder  native     
    return AndroidRuntime::registerNativeMethods(
        env, kBinderPathName,
        gBinderMethods, NELEM(gBinderMethods));
}

BinderInternal 클래스 초기 화
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
    jclass clazz;
//  BinderInternal            jclass  。     

   // “com/android/internal/os/BinderInternal”
    clazz = env->FindClass(kBinderInternalPathName);
    LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");

    gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    //  forceBinderGc methodID
    gBinderInternalOffsets.mForceGc
        = env->GetStaticMethodID(clazz, "forceBinderGc", "()V");
    assert(gBinderInternalOffsets.mForceGc);
  //  BinderInternal  native     
    return AndroidRuntime::registerNativeMethods(
        env, kBinderInternalPathName,
        gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

BinderProxy 클래스 초기 화
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
    jclass clazz;

    clazz = env->FindClass("java/lang/ref/WeakReference");
    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference");
    //gWeakReferenceOffsets   WeakReference    
    gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
      //  WeakReference get   MethodID
    gWeakReferenceOffsets.mGet
        = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");
    assert(gWeakReferenceOffsets.mGet);
//gErrorOffsets   Error    
    clazz = env->FindClass("java/lang/Error");
    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error");
     //gBinderProxyOffsets   BinderProxy    
    gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    //  BinderProxy     
    clazz = env->FindClass(kBinderProxyPathName);
    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");

    gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    gBinderProxyOffsets.mConstructor
        = env->GetMethodID(clazz, "", "()V");
    assert(gBinderProxyOffsets.mConstructor);
    gBinderProxyOffsets.mSendDeathNotice
        = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
    assert(gBinderProxyOffsets.mSendDeathNotice);

    gBinderProxyOffsets.mObject
        = env->GetFieldID(clazz, "mObject", "I");
    assert(gBinderProxyOffsets.mObject);
    gBinderProxyOffsets.mSelf
        = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
    assert(gBinderProxyOffsets.mSelf);
 //  BinderProxy native     
    return AndroidRuntime::registerNativeMethods(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

int_register_android_os_BinderProxy 함 수 는 BinderProxy 클래스 를 초기 화 하 는 것 외 에 WeakReference 클래스 와 Error 클래스 의 일부 정 보 를 얻 었 습 니 다.
하나의 예 를 통 해 자바 Binder 의 작업 절 차 를 분석 하고 먼저 AMS 가 자신 을 ServiceManager 에 어떻게 등록 하 는 지 분석 한 다음 에 AMS 가 클 라 이언 트 의 Binder 호출 요청 에 어떻게 응답 하 는 지 분석 합 니 다.frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
public static void setSystemProcess() {
        try {
            ActivityManagerService m = mSelf;
              // ActivityManagerService     ServiceManager 
            ServiceManager.addService("activity", m);
            ServiceManager.addService("meminfo", new MemBinder(m));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(m));
            }
            ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m));
            ServiceManager.addService("activity.services", new ServicesBinder(m));
            ServiceManager.addService("activity.senders", new SendersBinder(m));
            ServiceManager.addService("activity.providers", new ProvidersBinder(m));
            ServiceManager.addService("permission", new PermissionController(m));

            ApplicationInfo info =
                mSelf.mContext.getPackageManager().getApplicationInfo(
                        "android", STOCK_PM_FLAGS);
            synchronized (mSelf) {
                ProcessRecord app = mSelf.newProcessRecordLocked(
                        mSystemThread.getApplicationThread(), info,
                        info.processName);
                app.persistent = true;
                app.pid = Process.myPid();
                app.maxAdj = SYSTEM_ADJ;
                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
                synchronized (mSelf.mPidsSelfLocked) {
                    mSelf.mPidsSelfLocked.put(app.pid, app);
                }
                mSelf.updateLRUListLocked(app, true);
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }
    }

위 에서 보 여 준 코드 줄 의 목적 은 Activity Manager 서비스 서 비 스 를 ServiceManager 에 추가 하여 어떻게 등록 하 는 것 입 니까?
서비스 frameworks\base\core\java\android\os\\ServiceManager.java 를 ServiceManager 에 등록 합 니 다.
 /**
     * Place a new @a service called @a name into the service
     * manager.
     * 
     * @param name the name of the new service
     * @param service the service object
     */
    public static void addService(String name, IBinder service) {
        try {
          //getIServiceManager    
            getIServiceManager().addService(name, service);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

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

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

asInterface 의 인 자 는 BinderInternal.getContextObject 의 반환 값 입 니 다.이것 은 native 함수 입 니 다.그 실현 코드 는 frameworks\base\core\jni\android 입 니 다.util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
     // Native      Java  ,       
    return javaObjectForIBinder(env, b);
}


jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    if (val == NULL) return NULL;

    if (val->checkSubclass(&gBinderOffsets)) {
        // One of our own!
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        //printf("objectForBinder %p: it's our own %p!
", val.get(), object);
return object; } // For the rest of the function we will hold this lock, to serialize // looking/creation of Java proxies for native Binder proxies. //mProxyLock CMutex AutoMutex _l(mProxyLock); // Someone else's... do we know about it? /* val BpBinder, BpBinder.cpp findObject 。 , Native BpBinder ObjectManager, Native BpBinder Java BpBinder 。 findObject gBinderProxyOffsets ObjectManager 。 , object */ jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet); if (res != NULL) { LOGV("objectForBinder %p: found existing %p!
"
, val.get(), res); return res; } LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get()); android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } // BinderProxy , Native BpBinder ObjectManager object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if (object != NULL) { LOGV("objectForBinder %p: created new %p!
"
, val.get(), object); // The proxy holds a reference to the native object. env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); val->incStrong(object); // The native object needs to hold a weak reference back to the // proxy, so we can retrieve the same proxy if it is still active. jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); /* BinderProxy (attach) BpBinder ObjectManager , proxy_cleanup。 BinderProxy (detach) , , 。 proxy_cleanup 。 */ val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); // Note that a new object reference has been created. // Proxy android_atomic_inc(&gNumProxyRefs); // 。 Proxy 200 , // BinderInter ForceGc incRefsCreated(env); } return object; }

ServiceManager Native 클래스 의 asInterface 함수 frameworks\base\\core\\java\android\os\\ServiceManager Native.java 분석
/**
     * Cast a Binder object into a service manager interface, generating
     * a proxy if needed.
     */
    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        // obj   ,    ServiceManagerProxy  
        return new ServiceManagerProxy(obj);
    }

addService 함수 분석 분석 ServiceManager Proxy 의 addService 함수
public void addService(String name, IBinder service)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
         //      writeStrongBinder  ,          
        data.writeStrongBinder(service);
        //mRemote     BinderProxy  ,    transact,         
        //    
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

BinderProxy 의 transact 는 native 함수 로 함 수 를 실현 하 는 코드 는 다음 과 같 습 니 다 frameworks\base\core\jni\androidutil_Binder.cpp
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
                                                jint code, jobject dataObj,
                                                jobject replyObj, jint flags)
{
    if (dataObj == NULL) {
        jniThrowException(env, "java/lang/NullPointerException", NULL);
        return JNI_FALSE;
    }
 // Java Parcel     Native Parcel  
    Parcel* data = parcelForJavaObject(env, dataObj);
    if (data == NULL) {
        return JNI_FALSE;
    }
     //           Parcel  
    Parcel* reply = parcelForJavaObject(env, replyObj);
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }
 // Java BinderProxy               Native BpBinder  
    IBinder* target = (IBinder*)
        env->GetIntField(obj, gBinderProxyOffsets.mObject);
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }

    LOGV("Java code calling transact on %p in Java object %p with code %d
"
, target, obj, code); //printf("Transact from Java code to %p sending: ", target); data->print(); // Native BpBinder , ServiceManager status_t err = target->transact(code, *data, reply, flags); //if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); if (err == NO_ERROR) { return JNI_TRUE; } else if (err == UNKNOWN_TRANSACTION) { return JNI_FALSE; } signalExceptionForError(env, obj, err); return JNI_FALSE; }

좋은 웹페이지 즐겨찾기