Android进程通信

Android进程通信采用的是Binder架构,Binder架构提供了服务端、Binder驱动、客户端三个模块。客户端获取服务端的远程引用调用服务端的方法。

1.Binder架构和流程图

Binder架构图
由图可知,客户端需要通过Binder驱动获取服务端的远程引用Binder对象mRemote,然后调用transact方法来触发服务端的onTransact方法,实现进程通信。

2. 获取mRemote对象

通过1中的分析我们知道调用流程,那需要思考怎么获取mRemote。接下来我们分析获取系统服务的Binder。
Context是抽象类,实际调用的是ContextImp.getSystemService

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
50
@Override
public Object getSystemService(String name) {
if (WINDOW_SERVICE.equals(name)) {
return WindowManagerImpl.getDefault();
} else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
synchronized (mSync) {
LayoutInflater inflater = mLayoutInflater;
if (inflater != null) {
return inflater;
}
mLayoutInflater = inflater =
PolicyManager.makeNewLayoutInflater(getOuterContext());
return inflater;
}
} else if (ACTIVITY_SERVICE.equals(name)) {
return getActivityManager();
} else if (INPUT_METHOD_SERVICE.equals(name)) {
return InputMethodManager.getInstance(this);
} else if (ALARM_SERVICE.equals(name)) {
return getAlarmManager();
} else if (ACCOUNT_SERVICE.equals(name)) {
return getAccountManager();
} else if (POWER_SERVICE.equals(name)) {
return getPowerManager();
} else if (CONNECTIVITY_SERVICE.equals(name)) {
return getConnectivityManager();
} else if (THROTTLE_SERVICE.equals(name)) {
return getThrottleManager();
} else if (WIFI_SERVICE.equals(name)) {
return getWifiManager();
} else if (NOTIFICATION_SERVICE.equals(name)) {
return getNotificationManager();
} else if (KEYGUARD_SERVICE.equals(name)) {
return new KeyguardManager();
} else if (ACCESSIBILITY_SERVICE.equals(name)) {
return AccessibilityManager.getInstance(this);
} else if (LOCATION_SERVICE.equals(name)) {
return getLocationManager();
} else if (SEARCH_SERVICE.equals(name)) {
return getSearchManager();
} else if (SENSOR_SERVICE.equals(name)) {
return getSensorManager();
} else if (STORAGE_SERVICE.equals(name)) {
return getStorageManager();
} else if (USB_SERVICE.equals(name)) {
return getUsbManager();
}

return null;
}

随便分析一个

1
2
3
4
5
6
7
8
9
10
private AlarmManager getAlarmManager() {
synchronized (sSync) {
if (sAlarmManager == null) {
IBinder b = ServiceManager.getService(ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
sAlarmManager = new AlarmManager(service);
}
}
return sAlarmManager;
}

ServiceManager.getService

1
2
3
4
5
6
7
8
9
10
11
12
13
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}

1
2
3
4
5
6
7
8
9
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}

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

BinderInternal.getContextObject()静态函数返回ServiceManager对应的全局Binder对象,该函数不需要任何参数,因为它的作用是固定的。而ServiceManager中管理的
所以Binder对象都死通过addService方法添加进去的,是系统的Service在Framework启动的的时候完成的。
ServiceManager管理所有的Service,客户端可以回去需要的Manager,ServiceManager是一个独立的进程,所以获取Manager的时候也是通过Binder通信获取的。

ServiceManagerNative.asInterface

1
2
3
4
5
6
7
8
9
10
11
12
13
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}

return new ServiceManagerProxy(obj);
}

最后其实返回ServiceManagerProxy对象,使用静态代理模式代理IBinder

ServiceManagerProxy.getService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}

public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}

最后调用的是传进去的Binder对象transact方法。
最后解释asInterface其实就是使用静态代理,最后返回包装后的接口Manager,里面其实调用的还是Binder。

3 自定义服务的代码

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public interface Manager extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
com.jc.service.Manager {
private static final java.lang.String DESCRIPTOR = "com.jc.service.Manager";

/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}

/**
* Cast an IBinder object into an com.jc.service.Manager interface,
* generating a proxy if needed.
*/
public static com.jc.service.Manager asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.jc.service.Manager))) {
return ((com.jc.service.Manager) iin);
}
return new com.jc.service.Manager.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_callBanzheng: {
data.enforceInterface(DESCRIPTOR);
this.callBanzheng();
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}

private static class Proxy implements com.jc.service.Manager {
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 callBanzheng() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_callBanzheng, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}

static final int TRANSACTION_callBanzheng = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}

public void callBanzheng() throws android.os.RemoteException;
}

首先可以看到asInterface(android.os.IBinder obj)获取的是Proxy代理对象,然后通过mRemote发送消息给Binder驱动,Binder驱动调用服务端的onTransact,根据code判断调用的方法。

4. 总结

ServiceManager是一个全局的Binder管理者,系统的重要进程都在开启的时候通过ServiceManagerProxy向ServiceManager中添加自己,ServiceManagerProxy是一个BpBinder(0)的代理对象。
添加完成以后所以的进程可以通过ServiceManager获取其他进程的Binder远程引用对象,从而调用其他进程中的方法。

友情提示,这里讲到的主要是进程通信的基本流程,也是作为自己看书的部分记录。详细了解请看Android进程通信简要介绍和学习计划