本文创建了一个独立进程的service,通过bind方式来绑定服务,并通过binder与service进行交互。基于此来分析binder交互机制。
Service的创建与使用
定义aidl接口:
1 2 3 4 5 6 7 8 9
| interface IRemote { void setCallback(RemoteCallback callback); }
interface RemoteCallback { void callback(String content); }
|
IRemote是service的对外接口,TalkCallback则用于从service回调client端,加入TalkCallback是为了更好的理解service和client相互调用的流程。
定义完aidl后,编译一遍项目,这样就可以生成对应的java类,对应的java类在app/build/generated/aidl_source_output_dir
目录下。
定义Service:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class RemoveService extends Service { public RemoveService() {}
@Override public IBinder onBind(Intent intent) { return binder; }
private final IBinder binder = new IRemote.Stub() { @Override public void setCallback(RemoteCallback callback) throws RemoteException { callback.callback("I'm Service"); } }; }
|
因为我们要定义一个独立进程的service,所以在AndroidManifest.xml要声明android:process
属性,如下:
1 2 3 4 5
| <service android:name=".RemoveService" android:enabled="true" android:exported="false" android:process=":remote"/>
|
这样一个独立进程的service就定义完成了,然后就可以使用了。
绑定服务:
我们在MainActivity
中绑定service进行交互:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| private fun testService() { bindService(Intent(this, RemoveService::class.java), object : ServiceConnection { override fun onServiceConnected( name: ComponentName?, service: IBinder? ) { val proxy = IRemote.Stub.asInterface(service) proxy.setCallback(object : RemoteCallback.Stub() { override fun callback(content: String?) { Log.d("RemoteCallback", "callback message: $content") } }) }
override fun onServiceDisconnected(name: ComponentName?) {}
}, Context.BIND_AUTO_CREATE) }
|
IRemote.aidl的java实现
1 2 3 4
| public interface IRemote extends android.os.IInterface { public void talkAsync(me.rjy.android.demo.TalkCallback callback) throws android.os.RemoteException; }
|
IRemote.aidl生成的IRemote.java是一个接口类,具体的实现都在IRemote.Stub
这个的静态内部类中,而且Stub还包含Proxy静态内部类。下面是它们的类图关系:
下面是IRemote
的内部类Stub
的源码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public static abstract class Stub extends android.os.Binder implements me.rjy.android.demo.IRemote { private static final java.lang.String DESCRIPTOR = "me.rjy.android.demo.IRemote"; public Stub() { this.attachInterface(this, DESCRIPTOR); } public static me.rjy.android.demo.IRemote asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof me.rjy.android.demo.IRemote))) { return ((me.rjy.android.demo.IRemote)iin); } return new me.rjy.android.demo.IRemote.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 { java.lang.String descriptor = DESCRIPTOR; switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(descriptor); return true; } case TRANSACTION_setCallback: { data.enforceInterface(descriptor); me.rjy.android.demo.RemoteCallback _arg0; _arg0 = me.rjy.android.demo.RemoteCallback.Stub.asInterface(data.readStrongBinder()); this.setCallback(_arg0); reply.writeNoException(); return true; } default: { return super.onTransact(code, data, reply, flags); } } } static final int TRANSACTION_setCallback = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); ...... }
|
RemoveService的IBinder onBind(Intent intent)
方法返回的就是IRemote.Stub
的实现类:
1 2 3 4 5 6 7 8 9 10 11 12
| public class RemoveService extends Service { @Override public IBinder onBind(Intent intent) { return binder; } private final IBinder binder = new IRemote.Stub() { @Override public void setCallback(RemoteCallback callback) throws RemoteException { callback.callback("I'm Service"); } }; }
|
所以,Stub是在服务端。
Service绑定流程
zenuml
group App {
<<App>> MainActivity
<<App>> ContextImpl
<<App>> ServiceDispatcher
<<App>> InnerConnection
}
group AMS {
<<AMS>> ActivityManagerService
<<AMS>> ActiveServices
}
MainActivity->ContextImpl.bindService {
bindServiceCommon {
"LoadedApk.getServiceDispatcher" {
new ServiceDispatcher() {
new InnerConnection()
}
}
ActivityManagerService.bindServiceInstance {
ActiveServices.bindServiceLocked {
retrieveServiceLocked
InnerConnection.connected {
ServiceDispatcher.connected {
"Handler.post RunConnection()"
}
}
}
}
}
}
ServiceDispatcher->ServiceDispatcher."RunConnection.run() -> doConnected" {
MainActivity.onServiceConnected
}
service的绑定过程用到了ServiceDispatcher和InnerConnection,来看下两者的类图结构:
IServiceConnection是一个binder接口,app是service端,ams是client端,当绑定成功后,ams通过IServiceConnection来通知app绑定成功。
writeStrongBinder
1 2 3 4 5 6 7
| @FastNative private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
public final void writeStrongBinder(IBinder val) { nativeWriteStrongBinder(mNativePtr, val); }
|
nativeWriteStrongBinder是native函数,对应的c++的实现源码如下:
1 2 3 4 5 6 7 8 9 10 11
| 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); } } }
|