国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android Binder通信原理(五):Java 端的service 注冊和獲取

這篇具有很好參考價值的文章主要介紹了Android Binder通信原理(五):Java 端的service 注冊和獲取。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

源碼基于:Android R

0. 前言

在闡述相關(guān)的知識點,先整理個框架圖,后面帶著框架圖來分析過程:

Android Binder通信原理(五):Java 端的service 注冊和獲取

Java 端對于binder 使用大致分為:

  • Java client Java service
  • Java client native service

Java 端service 的注冊使用 ServiceManager.addService()

Java 端service 的獲取使用 ServiceManager.getService()

入口都是通過 ServiceManager.java,文件位于frameworks/base/core/java/android/os/ServiceManager.java

在分析addService 和getService 之前,需要了解Binder 最終是會調(diào)用到native 端,那么,Java 中間就需要通過JNI,所以在此之前需要了解JNI 的注冊過程。

1. Binder JNI 注冊

了解zygote 啟動過程的同學(xué)應(yīng)該知道 zygote 在啟動時首先會創(chuàng)建虛擬機,然后再通過 startReg() 注冊系統(tǒng)所需要的JNI 接口。

frameworks/base/core/jni/AndroidRuntime.cpp

/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    ...
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    ...
}

注冊的接口定義在:

frameworks/base/core/jni/AndroidRuntime.cpp

static const RegJNIRec gRegJNI[] = {
        REG_JNI(register_com_android_internal_os_RuntimeInit),
        REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
        REG_JNI(register_android_os_SystemClock),
        REG_JNI(register_android_util_EventLog),
        REG_JNI(register_android_util_Log),
        REG_JNI(register_android_util_MemoryIntArray),
        ...
        REG_JNI(register_android_os_Binder),
        ...

數(shù)組很長,這里不過多粘貼,binder 相關(guān)的注冊函數(shù)有:

        REG_JNI(register_android_os_Binder),

最終會調(diào)用到函數(shù)register_android_os_Binder():

frameworks/base/core/jni/android_util_Binder.cpp

int register_android_os_Binder(JNIEnv* env)
{
    if (int_register_android_os_Binder(env) < 0)
        return -1;
    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;
    ...

剩下來就不過多分析了,感興趣的同學(xué)可以進入詳細查看源碼流程 (當(dāng)然,下面遇到也會順帶分析下),這里只需要知道的是Java 端的Binder 需要native 操作的JNI 接口都是在zygote 啟動時就注冊好了。

2. ServiceManager 的代理

無論是ServiceManager.addService() 還是ServiceManager.getService() 最終都是需要與native 通信,那需要獲取到 ServiceManager 的代理。即函數(shù) getIServiceManager()

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

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

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

這里主要關(guān)注兩點:

  • BidnerInternal.getcontextObject()
  • ServiceManagerNative.asInterface()

2.1 BinderInternal.getContextObject()

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

public static final native IBinder getContextObject();

這個需要調(diào)用 JNI 接口,而這個接口注冊在第 1 節(jié)已經(jīng)闡述過,詳細看int_register_android_os_BinderInternal()

frameworks/base/core/jin/android_util_Binder.cpp

static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    ...
    }
};
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
    ...
    return RegisterMethodsOrDie(
env, kBinderInternalPathName,
 gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

通過注冊 gBinderInternalMethods 數(shù)組得知,最終調(diào)用接口android_os_BinderInternal_getContextObject():

frameworks/base/core/jin/android_util_Binder.cpp

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}

這里很熟悉了,獲取的是 context 為 0 的servicemanager 的BpBinder,并將BpBinder 通過函數(shù)javaObjectForIBinder()?轉(zhuǎn)換成Java 的 BinderProxy 對象返回。

2.1.1?javaObjectForIBinder()

frameworks/base/core/jin/android_util_Binder.cpp

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    ...
    BinderProxyNativeData* nativeData = new BinderProxyNativeData();
    nativeData->mOrgue = new DeathRecipientList;
    nativeData->mObject = val;

    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
    if (env->ExceptionCheck()) {
        // In the exception case, getInstance still took ownership of nativeData.
        return NULL;
    }
    ...

    return object;
}

這里主要通過CallStaticObjectMethod() 調(diào)用BinderProxy 中的 geInstance(),而這里的全局對象 gBinderProxyOffsets 是在 int_register_android_os_BinderProxy() 中指定的:

frameworks/base/core/jin/android_util_Binder.cpp

static int int_register_android_os_BinderProxy(JNIEnv* env)
{
    gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));
    gErrorOffsets.mOutOfMemory =
        MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));
    gErrorOffsets.mStackOverflow =
        MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));

    jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
            "(JJ)Landroid/os/BinderProxy;");
    gBinderProxyOffsets.mSendDeathNotice =
            GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
                                   "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
    gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");

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

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

javaObjectForIBinder() 需要通過 CallStaticObjectMethod() 函數(shù)調(diào)用?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);
                if (result != null) {
                    return result;
                }
                result = new BinderProxy(nativeData);
            } catch (Throwable e) {
                ...
            }
            ...
        }
        return result;
    }

至此,可知?BidnerInternal.getcontextObject() 獲取的是context 為0 的 BinderProxy 對象。

2.2?ServiceManagerNative.asInterface()

framworks/base/core/java/android/os/ServiceManagerNative.java

    public static IServiceManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }

        // ServiceManager is never local
        return new ServiceManagerProxy(obj);
    }

BinderProxy 對象獲取到后,通過asInterface,創(chuàng)建ServiceManager 的Java 端代理ServiceManagerProxy:

framworks/base/core/java/android/os/ServiceManagerNative.java

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
        mServiceManager = IServiceManager.Stub.asInterface(remote);
    }
    ...
    public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
            throws RemoteException {
        mServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }
    ...
    private IBinder mRemote;
    private IServiceManager mServiceManager;
}

mRemote 為BinderProxy 對象,mServiceManager 則是所有接口的入口,ServiceManager的真正proxy,下面會繼續(xù)分析。

3. ServiceManager.addService()

通過第 2 節(jié),我們得知,Java 端進行binder 通信,可能是client 通過ServiceManager.getService()?獲取到的server 代理,也可能是server 端通過ServiceManager.addService() 將service 注冊到ServiceManager 中。但無論哪個接口,都是通過ServiceManager 在java 端的代碼 BinderProxy 進行操作的。

這一節(jié)分析下addService():

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

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

getIServiceManager() 就是上面第 2.2 節(jié)返回的ServiceManagerProxy 對象,如果上面 2.2 節(jié)代碼所示,addService() 最終調(diào)用的是 mServiceManager.addService(),而這個mServiceManager 則是將上文講到的context 0 的BinderProxy 對象作為參數(shù)帶入通過IServiceManager 獲取的代理:

 mServiceManager = IServiceManager.Stub.asInterface(remote);

繼續(xù)分析。

通常andorid 都會將 *.aidl 文件編譯成對應(yīng)的 java 文件,而最終的 java 源碼是在out/soong/.intermediates/ 下,詳細看本系列文章中的第七篇:Java 下的C-S

aidl 編譯后的JAVA 文件都會最終打包到aidl*.srcjar 中,那具體的文件怎么確定呢?需要依賴frameworks 文件夾或者system 文件夾的 *.aidl.d 文件。

如果aidl 文件是定義在frameworks 下,那么就可以到framework 下對應(yīng)的目錄查找對應(yīng)的 *.aidl.d 文件。

這個的 IServiceManager 就是 IServiceManager.aidl 編譯后的類名

      @Override public void addService(java.lang.String name, android.os.IBinder service, boolean allowIsolated, int dumpPriority) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeStrongBinder(service);
          ...
          boolean _status = mRemote.transact(Stub.TRANSACTION_addService, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            getDefaultImpl().addService(name, service, allowIsolated, dumpPriority);
            return;
          }
          _reply.readException();
        }
        ...
      }

proxy 的代碼比較簡單:

  • 通過接口writeStrongBinder() 將需要添加的 service 寫到 Parcel 中;
  • 通過mRemote.transact() 進行通信,確認是否達到addService() 目的;
  • 如果上面失敗,則嘗試通過 getDefaultImpl() 進行 addService();

通常是走第二步,第三步的default impl 需要通過接口 setDefaultImpl() 指定。

通過第 2.2 節(jié)獲悉,mRemote 就是ServiceManager 的java 端BinderProxy 對象。

3.1 writeStrongBinder()

frameworks/base/core/java/android/os/Parcel.java

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

JNI 接口位于android_os_Parcel.cpp 中,而此接口也是在zygote 啟動是加載。這里不過多分析,詳細請查看 AndroidRuntime.cpp 中數(shù)組 gRegJNI 里的成員 register_android_os_Parcel。

最終調(diào)用到JNI android_os_Parcel_writeStrongBinder():

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

來看下核心的 ibinderForJavaObject():

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

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

純正的service 屬于 Binder 類型,所以匹配時與gBinderOffsets.mClass 匹配,該變量是也是在注冊的時候賦值,詳細看 int_register_android_os_Binder()。

gBinderOffsets.mObject 獲取的是 Binder.java 中的 mObject 對象(詳細看int_register_android_os_Binder函數(shù)),也就是在Binder 構(gòu)造時,從native 獲取的 BBinderHolder 指針:

frameworks/base/core/java/android/os/Binder.java

    public Binder(@Nullable String descriptor)  {
        mObject = getNativeBBinderHolder();

        ...
    }

---->?

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

ibinderForJavaObject() 除了上面獲取到的JavaBBinderHolder,最終就是通過該 holder 調(diào)用 get()接口,獲取 servcie 的BBinder:

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

        return b;
    }

來看下JavaBBinder:

frameworks/base/core/jni/android_util_Binder.cpp

class JavaBBinder : public BBinder
{
    ...
}

所以,writeStrongBinder() 最終就是 native 中 BBinder 寫入parcel 傳入transact()。

3.2 BinderProxy.transact()

詳細看第 5節(jié)

3.3 JavaBBinder.onTransact()

當(dāng)Client 通過 transact() 進行通信時,最終 BBinder 會觸發(fā)onTransact(),對于java service,最終觸發(fā)的就是 JavaBBinder.onTransact()

frameworks/base/core/jni/android_util_Binder.cpp

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

gBinderOffsets.mExecTransact 也是int_register_android_os_Binder() 賦值,調(diào)用的是Binder.java 中execTransact(),這里不過多闡述,最終調(diào)用stub.onTransact。

4. ServiceManager.getService()

同addService,getService 最終也是調(diào)用到IServiceManager中:

      @Override public android.os.IBinder checkService(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 {
          ...
          boolean _status = mRemote.transact(Stub.TRANSACTION_checkService, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) {
            return getDefaultImpl().checkService(name);
          }
          _reply.readException();
          _result = _reply.readStrongBinder();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }

        return _result;
      }

同理addService(),這里會通過 _reply.readStrongBinder() 獲得native 端傳過來的binder 信息。

4.1?readStrongBinder()

最終會調(diào)用到JNI android_os_Parcel.cpp

frameworks/base/core/jni/android_os_Parcel.cpp

static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}

2.1 節(jié)已經(jīng)分析過了,最終通過javaObjectForIBinder() 獲取到 service 在java 端的BinderProxy 對象。

5.?BinderProxy.transact()

frameworks/base/core/java/android/os/BinderProxy.java

    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");

        ....
        try {
            return transactNative(code, data, reply, flags);
        } finally {
            ...
        }
    }

其實這里核心就是調(diào)用transactNative:

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
{
    ...

    status_t err = target->transact(code, *data, reply, flags);
    ...
}

接下來就是BpBinder->transact,看詳細看本系列文章中的第三篇:service 注冊

6. 總結(jié)?

Android Binder通信原理(五):Java 端的service 注冊和獲取

最后再來根據(jù)框架圖進行總結(jié):文章來源地址http://www.zghlxwxcb.cn/news/detail-503464.html

  • Java client 通過getService() 獲取service 的代理,getService() 最后會通過readStrongBinder()?獲取 BinderProxy 對象;
  • Java client 通過transact 與service 通信,通過native 接口 transactNative() 調(diào)用到BpBinder;
  • Java service 通過addService() 注冊,addService() 會通過writeStrongBinder() 調(diào)用native 接口注冊到JNI;
  • Java service 注冊時,會在JNI 中創(chuàng)建 JavaBBinderHolder,這里封裝了與 native 通信的JavaBBinder,而JavaBBinder 就是繼承自BBinder;
  • Java client 的調(diào)用對于 java service 最終會調(diào)用 onTransact(),并回調(diào)到j(luò)ava 端stub.onTransact();

到了這里,關(guān)于Android Binder通信原理(五):Java 端的service 注冊和獲取的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Android Binder——Java層通信實例(十六)

    ??????? 前面的文章中我們介紹了 Java 層服務(wù)的注冊流程,以及代理文件的查找。這里我們看一個 Binder 通信的實例,為了方便我們就以 Android 源碼中現(xiàn)有的功能 PMS 的 install 為例,PMS 在進行 APK 安裝時,會進行 dex 的翻譯,依賴守護進程 installd 完成。 ??????? 在 Binder

    2024年04月23日
    瀏覽(23)
  • Binder通信原理

    Binder通信原理

    注:本文大部分代碼來自安卓11 ● 從IPC角度來說,Binder是Android中的一種跨進程通信方式,Binder還可以理解為一種虛擬的物理設(shè)備驅(qū)動,它的設(shè)備驅(qū)動是/dev/binder,該通信方式以前在linux中沒有 ● 從Android Framework角度來說,Binder是ServiceManager連接各種Manager(ActivityManager、Windo

    2024年02月03日
    瀏覽(18)
  • [Android 13]Binder系列--獲取服務(wù)

    [Android 13]Binder系列--獲取服務(wù)

    獲取服務(wù) hongxi.zhu 2023-7-8 以 SurfaceFlinger 進程中獲取 InputFlinger 服務(wù)為例 frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp 獲取到SM的代理對象之前的文章已經(jīng)分析過,請參考前面的:Binder系列–獲取ServiceManager BpServiceManager::getService remote()從前面可知是SM的BpBinder對象,獲取到SM的

    2024年02月13日
    瀏覽(23)
  • Android Binder常用案例使用分析,跨進程通信aidl

    Android Binder常用案例使用分析,跨進程通信aidl

    service組件的binderService獲取binder通信。 servicemanager.getService方法獲取相關(guān)服務(wù)。 本質(zhì)上都是IBinder通信。 客戶端:使用intent,啟動服務(wù)端的service,使用binderservice,在onServiceConnected回調(diào)方法中獲取服務(wù)端的實際binder對象。使用aidl中的接口調(diào)用服務(wù)端的方法即可。 服務(wù)端:定義

    2024年02月07日
    瀏覽(30)
  • Android 進階——Binder IPC之Binder IPC架構(gòu)及原理概述(九)

    Android 進階——Binder IPC之Binder IPC架構(gòu)及原理概述(九)

    前面幾篇文章,為我們學(xué)習(xí)Binder IPC通信機制提供了扎實的理論基礎(chǔ),接下來將正式進入Binder IPC通信架構(gòu)及原理的解讀。 Binder 是基于 C/S 架構(gòu)的,由一系列的組件組成,包括 Client進程、Server進程、Service Manager進程、Binder 驅(qū)動。其中 Client進程、Server進程、Service Manager進程運行

    2023年04月09日
    瀏覽(20)
  • Android Binder機制淺談以及使用Binder進行跨進程通信的倆種方式(AIDL以及直接利用Binder的transact方法實現(xiàn))

    Android Binder機制淺談以及使用Binder進行跨進程通信的倆種方式(AIDL以及直接利用Binder的transact方法實現(xiàn))

    Binder機制學(xué)習(xí) ·為何新增Binder來作為主要的IPC方式 Android也是基于Linux內(nèi)核,Linux現(xiàn)有的進程通信手段有管道/消息隊列/共享內(nèi)存/套接字/信號量。 既然有現(xiàn)有的IPC方式,為什么重新設(shè)計一套Binder機制呢? 主要是出于以上三個方面的考量: 2. binder是什么? 從進程間通信的角度

    2024年02月16日
    瀏覽(27)
  • BpBinder與PPBinder調(diào)用過程——Android開發(fā)Binder IPC通信技術(shù)

    BpBinder與PPBinder調(diào)用過程——Android開發(fā)Binder IPC通信技術(shù)

    在Android系統(tǒng)中,進程間通信(IPC)是一個非常重要的話題。Android系統(tǒng)通過Binder IPC機制實現(xiàn)進程間通信,而Binder IPC通信技術(shù)則是Android系統(tǒng)中最為重要的進程間通信技術(shù)之一。本文將介紹Binder IPC通信技術(shù)的原理,并詳細解析BpBinder與PPBinder調(diào)用過程的使用以及注意事項。 Bind

    2024年02月13日
    瀏覽(26)
  • 寫給 Android 應(yīng)用工程師的 Binder 原理剖析

    寫給 Android 應(yīng)用工程師的 Binder 原理剖析

    這篇文章我醞釀了很久,參考了很多學(xué)習(xí)文檔,讀了很多源碼,卻依舊不敢下筆。生怕自己理解上還有偏差,對大家造成誤解,貽笑大方。又怕自己理解不夠透徹,無法用清晰直白的文字準確的表達出 Binder 的設(shè)計精髓。直到今天提筆寫作時還依舊戰(zhàn)戰(zhàn)兢兢。 Binder 之復(fù)雜遠遠

    2024年02月13日
    瀏覽(24)
  • [Nacos] Nacos Client獲取所有服務(wù)和定時更新Client端的注冊表 (三)

    [Nacos] Nacos Client獲取所有服務(wù)和定時更新Client端的注冊表 (三)

    Nacos的服務(wù)發(fā)現(xiàn)功能: 獲取所有服務(wù), 定時更新Client端的注冊表 1.Nacos Client獲取所有服務(wù) 1.1 Client如何獲取所有服務(wù) NacosDiscoveryClientAutoConfiguration.java NacosDiscoveryClient#getServices() 這里的discoveryProperties為上面的NacosDiscoveryClientAutoConfiguration自動注入了。 DiscoveryClientHealthIndicator為Spr

    2024年02月13日
    瀏覽(25)
  • Android復(fù)習(xí)(Android基礎(chǔ)-四大組件)——Service與Activity通信

    Android復(fù)習(xí)(Android基礎(chǔ)-四大組件)——Service與Activity通信

    我們前面學(xué)會了啟動和停止服務(wù)的方法,但是服務(wù)雖然是在活動里啟動的,但是啟動服務(wù)之后,活動與服務(wù)之間基本沒什么關(guān)系了。 正常情況,我們在Activity里調(diào)用startService()方法啟動MyService這個服務(wù),然后MyService的onCreate()和onStartCommand()方法就會得到執(zhí)行。之后服務(wù)會一直處

    2024年02月13日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包