通过自定义Service理解Binder

本文创建了一个独立进程的service,通过bind方式来绑定服务,并通过binder与service进行交互。基于此来分析binder交互机制。

Service的创建与使用

定义aidl接口:

1
2
3
4
5
6
7
8
9
//IRemote.aidl
interface IRemote {
void setCallback(RemoteCallback callback);
}

//RemoteCallback.aidl
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 {
//收到client端的函数调用,并回调client端
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)
//通过binder调用service的setCallback接口
proxy.setCallback(object : RemoteCallback.Stub() {
override fun callback(content: String?) {
//收到service的回调消息
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静态内部类。下面是它们的类图关系:

android.os.IInterfaceandroid.os.Binderandroid.os.IBinderIRemoteIRemote.StubIRemote.Stub.Proxyandroid.os.IBinder mRemote;

下面是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; }

//onTransact是binder跨进程通信的关键函数
@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); //调用RemoveService.binder.setCallback
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,来看下两者的类图结构:

LoadedApk.ServiceDispatcher.InnerConnectionIServiceConnection.StubLoadedApk.ServiceDispatcherServiceConnection

IServiceConnection是一个binder接口,app是service端,ams是client端,当绑定成功后,ams通过IServiceConnection来通知app绑定成功。

writeStrongBinder

1
2
3
4
5
6
7
//frameworks\base\core\java\android\os\Parcel.java
@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
//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);
}
}
}