不少文章將Binder框架定義了四個角色:Server,Client,ServiceManager、以及Binder驅動,但這容易將人引導到歧途:好像全部的Binder服務都須要去ServiceManager去註冊才能使用,其實不是這樣。例如,平時APP開發經過bindService啓動的服務,以及有些本身定義的AIDL遠程調用,都不必定都ServiceManager註冊這條路,我的理解:ServiceManager主要功能是:管理系統服務,好比AMS、WMS、PKMS服務等,而APP經過的bindService啓動的Binder服務實際上是由SystemServer的ActivityManagerService負責管理。這篇主要關注Android APP Java層Binder通訊一些奇葩點:java
ServiceManager其實主要的面向對象是系統服務,大部分系統服務都是由SystemServer進程總添加到ServiceManager中去的,在經過ServiceManager添加服務的時候,是有些權限校驗的,源碼以下:node
int svc_can_register(unsigned uid, uint16_t *name) { unsigned n; // 誰有權限add_service 0進程,或者 AID_SYSTEM進程 if ((uid == 0) || (uid == AID_SYSTEM)) return 1; for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++) if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name)) return 1; return 0; }複製代碼
能夠看到 (uid == 0) 或者 (uid == AID_SYSTEM)的進程都是能夠添加服務的,uid=0,表明root用戶,而uid=AID_SYSTEM,表明系統用戶 。或者是一些特殊的配置進程。SystemServer進程在被Zygote建立的時候,就被分配了UID 是AID_SYSTEM(1000),android
private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException { /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007", "--capabilities=130104352,130104352", "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", };複製代碼
Android每一個APP的UID,都是不一樣的,用了Linux的UID那一套,可是沒徹底沿用,這裏不探討,總之,普通的進程是沒有權限註冊到ServiceManager中的,那麼APP平時經過bindService啓動的服務怎麼註冊於查詢的呢?接管這個任務的就是SystemServer的ActivityManagerService。緩存
bindService比startService多了一套Binder通訊,其他的流程基本相同,而startService的流程,同startActivity差很少,四大組件的啓動流程這裏不作分析點,主要看bindService中C/S通訊的創建流程,在這個流程裏面,APP與服務端互爲C/S的特性更明顯,在APP開發的時候,binder服務是經過Service來啓動的。Service的啓動方式有兩種startService,與bindService,這裏只考慮後者,另外啓動的binder服務也分爲兩種狀況:第一種,client同server位於同一進程,能夠看作內部服務,第二種,Client與Server跨進程,即便是位於同一個APP,第一桶能夠不用AIDL來編寫,可是第二種必須經過AIDL實現跨進程通訊,看一個最簡單的AIDL例子,首先在定義一個aidl接口:markdown
IMyAidlInterface.aidlcookie
interface IMyAidlInterface {
void communicate(int count);
}app
IMyAidlInterface.aidl定義了通訊的藉口,經過build以後,構建工具會自動爲IMyAidlInterface.aidl生成一些輔助類,這些輔助類主要做用是生成Binder通訊協議框架,必須保證兩方通訊須要指令相同,才能解析通訊內容。天王蓋地虎,寶塔鎮河妖。Java層Binder的對應關係Binder與BinderProxy從這裏能夠看出,binder採用了代理模式 stub與proxy對應,使用aidl實現的服務時候,Client若是想要得到Binder實體的代理能夠經過asInterface來處理,好比若是在同一進程就是實體,不在就新建代理對象框架
public interface IMyAidlInterface extends android.os.IInterface { public static abstract class Stub extends android.os.Binder implements com.snail.labaffinity.IMyAidlInterface { private static final java.lang.String DESCRIPTOR = "com.snail.labaffinity.IMyAidlInterface"; public Stub() { this.attachInterface(this, DESCRIPTOR); } public static com.snail.labaffinity.IMyAidlInterface asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.snail.labaffinity.IMyAidlInterface))) { return ((com.snail.labaffinity.IMyAidlInterface) iin); } return new com.snail.labaffinity.IMyAidlInterface.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_communicate: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); this.communicate(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.snail.labaffinity.IMyAidlInterface { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public void communicate(int count) 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.writeInt(count); mRemote.transact(Stub.TRANSACTION_communicate, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_communicate = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } public void communicate(int count) throws android.os.RemoteException; }複製代碼
啓動Binder服務端封裝Service,之因此成爲封裝Service,是由於Service對於Binder實體的最大做用是個做爲新建服務的入口:ide
public class AidlService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return new BBinderService(); } public class BBinderService extends IMyAidlInterface.Stub { @Override public void communicate(int count) throws RemoteException { } } }複製代碼
而啓動的入口:函數
public class MainActivity extends AppCompatActivity { ... void bind(){ Intent intent = createExplicitFromImplicitIntent(MainActivity.this, new Intent("com.snail.labaffinity.service.AidlService")); bindService(intent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder); } @Override public void onServiceDisconnected(ComponentName componentName) { } }, Context.BIND_AUTO_CREATE); } }複製代碼
以上四個部分就組成了AIDL跨進程服務的基本組件,如今從ActivitybindService入口開始分析:bindService大部分的流程與startActivity相似,其實都是經過AMS啓動組件,這裏只將一些不一樣的地方,Activity啓動只須要Intent就能夠了,而Service的bind須要一個ServiceConnection對象,這個對象實際上是爲了AMS端在啓動Service後回調用的,ServiceConnection是個接口,其實例在ContextImpl的:
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, UserHandle user) { IServiceConnection sd; if (conn == null) { throw new IllegalArgumentException("connection is null"); } if (mPackageInfo != null) { sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), mMainThread.getHandler(), flags); } else { throw new RuntimeException("Not supported in system context"); } validateServiceIntent(service); try { IBinder token = getActivityToken(); if (token == null && (flags & BIND_AUTO_CREATE) == 0 && mPackageInfo != null && mPackageInfo.getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { flags |= BIND_WAIVE_PRIORITY; } service.prepareToLeaveProcess(); int res = ActivityManagerNative.getDefault().bindService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), sd, flags, getOpPackageName(), user.getIdentifier()); if (res < 0) { throw new SecurityException( "Not allowed to bind to service " + service); } return res != 0; } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } }複製代碼
mPackageInfo是一個LoadApk類,經過它的getServiceDispatcher得到一個IServiceConnection對象,這個對象一個Binder實體,看一下具體原理
public final IServiceConnection getServiceDispatcher(ServiceConnection c, Context context, Handler handler, int flags) { synchronized (mServices) { LoadedApk.ServiceDispatcher sd = null; ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); if (map != null) { sd = map.get(c); } if (sd == null) { sd = new ServiceDispatcher(c, context, handler, flags); if (map == null) { map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); mServices.put(context, map); } map.put(c, sd); } else { sd.validate(context, handler); } return sd.getIServiceConnection(); } }複製代碼
在LoadApk中IServiceConnection對象是經過context鍵值來存儲ServiceDispatcher對象,而ServiceDispatcher對象內存會有個InnerConnection對象,該對象就是getServiceDispatcher的返回對象。所以bindServiceCommon最終調用
ActivityManagerNative.getDefault().bindService(x,x,x,x,x sd, x, x, x) 的時候,傳遞的參數sd其實就是一個InnerConnection對象,這是個Binder實體。可是,Binder.java中的Binder只是對native層BBinder的一個簡單封裝,真正的實例化仍是經過JNI到native層去建立一個JavaBBinderHolder對象,並初始化gBinderOffsets,讓其能映射Java層Binder對象,而JavaBBinderHolder中又能夠實例化BBinder的實例JavaBBinder,不過BBinder的實例化時機並不在這裏,而是在Parcel對象writeStrongBinder的時候,
static struct bindernative_offsets_t { // Class state. jclass mClass; jmethodID mExecTransact; // Object state. jfieldID mObject; } gBinderOffsets; static void android_os_Binder_init(JNIEnv* env, jobject obj) { JavaBBinderHolder* jbh = new JavaBBinderHolder(); jbh->incStrong((void*)android_os_Binder_init); env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh); }複製代碼
繼續往下看bindService,會調用到ActivityManagerProxy的bindService
public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); data.writeStrongBinder(token); service.writeToParcel(data, 0); data.writeString(resolvedType); data.writeStrongBinder(connection.asBinder()); data.writeInt(flags); data.writeInt(userId); mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0); reply.readException(); int res = reply.readInt(); data.recycle(); reply.recycle(); return res; }複製代碼
利用Parcel的writeStrongBinder會將Binder實體寫入到Parcel中去,這裏首先看一下 Parcel data = Parcel.obtain();在java層Parcel只是一個容器,具體Parcel相關的操做都在Native層
static jint android_os_Parcel_create(JNIEnv* env, jclass clazz) { Parcel* parcel = new Parcel(); return reinterpret_cast<jint>(parcel); }複製代碼
這裏的返回值,其實就是Parcel對象的地址,被賦值給了Parcel.java的mNativePtr成員變量,方便Native調用,接着看writeStrongBinder的實現,其實就是調用Parcel.cpp中的對應方法,經過flatten_binder將Binder實體對象打扁,建立flat_binder_object寫入Parcel中,
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint 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主要爲Java層Binder實例化native binder對象:
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) { if (obj == NULL) return NULL; if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetIntField(obj, gBinderOffsets.mObject); return jbh != NULL ? jbh->get(env, obj) : NULL; } if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); } return NULL; }複製代碼
若是BBinder還沒實例化,要經過JavaBBinderHolder的get函數實例化一個BBinder對象,這裏就是JavaBBinder對象,綜上分析Java層與Native的Binder其對應關係以下:
BBinder對象被Parcel轉換成flat_binder_object,通過一次拷貝寫入目標進程,並執行BINDER_TYPE_BINDER與BINDER_TYPE_HANDLE的轉換,以下:
static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply) ... fp = (struct flat_binder_object *)(t->buffer->data + *offp); switch (fp->type) { case BINDER_TYPE_BINDER: case BINDER_TYPE_WEAK_BINDER: {.. if (fp->type == BINDER_TYPE_BINDER) fp->type = BINDER_TYPE_HANDLE; else fp->type = BINDER_TYPE_WEAK_HANDLE; fp->handle = ref->desc; } break; case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: {.. struct binder_ref *ref = binder_get_ref(proc, fp->handle); if (ref->node->proc == target_proc) { if (fp->type == BINDER_TYPE_HANDLE) fp->type = BINDER_TYPE_BINDER; else fp->type = BINDER_TYPE_WEAK_BINDER; fp->binder = ref->node->ptr; fp->cookie = ref->node->cookie; } else { struct binder_ref *new_ref; new_ref = binder_get_ref_for_node(target_proc, ref->node); fp->handle = new_ref->desc; } } break; }複製代碼
在內核中,bindService中的InnerConnection會由BINDER_TYPE_BINDER轉換成BINDER_TYPE_HANDLE,以後,AMS線程被喚醒後,執行後面的流程,在前文分析Parcel數據轉換的時候,在Binder線程被喚醒繼續執行的時候,會將數據映射到一個natvie Parcel對象中
status_t IPCThreadState::executeCommand(int32_t cmd) { BBinder* obj; switch (cmd) { .. // read到了數據請求,這裏是須要處理的邏輯 ,處理完畢, case BR_TRANSACTION: { binder_transaction_data tr; result = mIn.read(&tr, sizeof(tr)); Parcel buffer; <!--關鍵點1 --> buffer.ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), freeBuffer, this); ... <!--關鍵點2 --> if (tr.target.ptr) { sp<BBinder> b((BBinder*)tr.cookie); const status_t error = b->transact(tr.code, buffer, &reply, tr.flags); if (error < NO_ERROR) reply.setError(error); } .. } } 複製代碼
首先看一下關鍵點1 ,這裏將內核數據映射到一個用戶空間的Parcel對象中去,以後在調用目標Service的transact函數,進而調用他的onTrasanct函數 , 經過前面的分析知道,Java層Binder在註冊時候,最終註冊的是JavaBBinder對象,看一下它的onTrasanct函數:
virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) { JNIEnv* env = javavm_to_jnienv(mVM); IPCThreadState* thread_state = IPCThreadState::self(); const int strict_policy_before = thread_state->getStrictModePolicy(); thread_state->setLastTransactionBinderFlags(flags); .. jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, (int32_t)&data, (int32_t)reply, flags); .. return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; }複製代碼
關鍵代碼只有一句:env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, (int32_t)&data, (int32_t)reply, flags),其實就是調用Binder.java的execTransact函數,該函數首先將Native的Parcel映射成Jave層Parcel,以後調用BBinder子類的onTransact函數執行對應的業務邏輯:
private boolean execTransact(int code, int dataObj, int replyObj, int flags) { Parcel data = Parcel.obtain(dataObj); Parcel reply = Parcel.obtain(replyObj); boolean res; try { res = onTransact(code, data, reply, flags); } ... reply.recycle(); data.recycle(); return res; }}複製代碼
對於AMS而bindService對應的操做以下
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { 。。 case BIND_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); IBinder token = data.readStrongBinder(); Intent service = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); b = data.readStrongBinder(); int fl = data.readInt(); int userId = data.readInt(); IServiceConnection conn = IServiceConnection.Stub.asInterface(b); int res = bindService(app, token, service, resolvedType, conn, fl, userId); reply.writeNoException(); reply.writeInt(res); return true; }複製代碼
b = data.readStrongBinder()會先讀取Binder對象,這裏會調用本地函數nativeReadStrongBinder(mNativePtr),mNativePtr就是Native層Parcel的首地址:
public final IBinder readStrongBinder() { return nativeReadStrongBinder(mNativePtr); }複製代碼
nativeReadStrongBinder(mNativePtr)會將本地Binder對象轉化成Java層對象,其實就是將傳輸的InnerConnection讀取出來,不過因爲Binder驅動將BINDER_TYPE_BINDER轉換成了BINDER_TYPE_HANDLE,對於AMS實際上是實例化BinderProxy
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { // /parcel->readStrongBinder() 其實就會建立BpBInder、 return javaObjectForIBinder(env, parcel->readStrongBinder()); } return NULL; }複製代碼
首先會利用Parcel.cpp的parcel->readStrongBinder(),讀取binder對象,這裏會根據flat_binder_object的類型,分別進行BBinder與BpBinder映射,若是是Binder實體直接將指針賦值out,若是不是,則根據handle獲取或者新建BpBinder返回給out。
status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out) { const flat_binder_object* flat = in.readObject(false); if (flat) { switch (flat->type) { case BINDER_TYPE_BINDER: *out = static_cast<IBinder*>(flat->cookie); return finish_unflatten_binder(NULL, *flat, in); case BINDER_TYPE_HANDLE: *out = proc->getStrongProxyForHandle(flat->handle); return finish_unflatten_binder( static_cast<BpBinder*>(out->get()), *flat, in); } } return BAD_TYPE; }複製代碼
以後會牽扯一個將native binder轉換成java層Binder的操做,javaObjectForIBinder,這個函數很關鍵,是理解Java層BinderProxy或者BBinder實體的關鍵:
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { if (val == NULL) return NULL; <!--關鍵點1--> if (val->checkSubclass(&gBinderOffsets)) { jobject object = static_cast<JavaBBinder*>(val.get())->object(); return object; } AutoMutex _l(mProxyLock); <!--關鍵點2--> jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } <!--關鍵點3--> object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if (object != NULL) { env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); val->incStrong((void*)javaObjectForIBinder); jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); sp<DeathRecipientList> drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get())); android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); } return object; }複製代碼
先看關鍵點1, checkSubclass默認返回false,可是JavaBBinder,該類對此函數進行了覆蓋,若是是JavaBBinder,就會返回true,但若是是BpBinder,則會返回false,
bool checkSubclass(const void* subclassID) const { return subclassID == &gBinderOffsets; }複製代碼
再看關鍵點2,若是是BpBinder,則須要首先在gBinderProxyOffsets中查找,是否是已經新建了Java層代理BinderProxy對象,若是沒有,則新建便可,若是新建過,就看是否還存在緩存有效的BinderProxy。最後看關鍵點3 :
env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor)
其實就是新建BinderProxy對象,Java層的BinderProxy都是Native新建的,Java層並無BinderProxy的新建入口,以後,再經過IServiceConnection.Stub.asInterface(b)進行轉換,實例化一個IServiceConnection.Proxy代理對,該對象在Binder通訊的基礎上封裝了業務邏輯,其實就是一些具體的操做。
public static XXXAidlInterface asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof XXXAidlInterface))) { return ((XXXAidlInterface) iin); } return new XXXAidlInterface.Stub.Proxy(obj); }複製代碼
這裏注意一點杜宇BinderProxy,obj.queryLocalInterface(DESCRIPTOR)返回爲null,對於Binder實體,返回的是Binder自身,這樣就能爲上層區分出是生成代理仍是存根自身,總體對象轉換流程以下:
到這裏分析了一半,Java層命令及回調Binder入口已經被傳遞給AMS,AMS以後須要負責啓動Service,並經過回調入口爲Client綁定服務,跟蹤到AMS源碼
public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId) { ... synchronized(this) { return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, userId); } }複製代碼
最後調用ActiveService的bindServiceLocked,這裏會分三中狀況,
不過這裏只討論「 Service未啓動,可是進程已經啓動的狀況」,關鍵代碼以下
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId) { try { .。。 if ((flags&Context.BIND_AUTO_CREATE) != 0) { s.lastActivity = SystemClock.uptimeMillis(); <!--關鍵點1--> if (bringUpServiceLocked(s, service.getFlags(), false) != null) { return 0; } } <!--關鍵點2--> .. requestServiceBindingLocked(s, b.intent, false); .. } }複製代碼
關鍵點1其實就是啓動Service,主要是經過ApplicationThread的binder通訊通知App端啓動Service,這個流程同Activity啓動同樣。關鍵點2是Service特有的:requestServiceBindingLocked,這個命令是告訴APP端:「在Service啓動後須要向AMS發消息,以後AMS才能向其餘須要綁定該Service的Client發送反饋」。
AMS端 private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean rebind) { if ((!i.requested || rebind) && i.apps.size() > 0) { .. r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); .. } } return true; } APP端 private void handleBindService(BindServiceData data) { Service s = mServices.get(data.token); ... if (!data.rebind) { IBinder binder = s.onBind(data.intent); ActivityManagerNative.getDefault().publishService( data.token, data.intent, binder); } }複製代碼
ActivityManagerNative.getDefault().publishService會將啓動的Binder服務實體傳遞給AMS,上面分析過Binder實體傳輸,這裏的原理是同樣的,AMS端在傳輸結束後,會得到Service端服務實體的引用,這個時候,就能經過最初的InnerConnection的回調將這個服務傳遞給Client端。Binder實體與引用的總體流程圖以下:
若是要深究Activity的bindService流程,能夠按如下幾步來分析
據說你Binder機制學的不錯,來解決下這幾個問題(一)
據說你 Binder 機制學的不錯,來解決下這幾個問題(二)
據說你 Binder 機制學的不錯,來解決下這幾個問題(三)
僅供參考,歡迎指正