Binder是Android中的跨进程通信方式,bindService的时候,服务端返回Binder对象,通过该对象客户端可以从服务端获取数据。
在进程间通信IPC——AIDL中创建了ICustomAidlInterface.aidl。
以下是根据ICustomAidlInterface.aidl生成的ICustomAidlInterface.Java接口类。

public interface ICustomAidlInterface extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements com.sjl.exercise.ICustomAidlInterface {
private static final java.lang.String DESCRIPTOR = "com.sjl.exercise.ICustomAidlInterface";

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

/**
* Cast an IBinder object into an com.sjl.exercise.ICustomAidlInterface interface,
* generating a proxy if needed.
*/
public static com.sjl.exercise.ICustomAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
//④
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.sjl.exercise.ICustomAidlInterface))) {
return ((com.sjl.exercise.ICustomAidlInterface) iin);
}
return new com.sjl.exercise.ICustomAidlInterface.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_getCurrentTime: {
data.enforceInterface(descriptor);
java.lang.String _result = this.getCurrentTime();
reply.writeNoException();
reply.writeString(_result);
return true;
}
case TRANSACTION_insertUser: {
data.enforceInterface(descriptor);
com.sjl.exercise.bean.UserBean _arg0;
if ((0 != data.readInt())) {
_arg0 = com.sjl.exercise.bean.UserBean.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
this.insertUser(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getUsers: {
data.enforceInterface(descriptor);
java.util.List<com.sjl.exercise.bean.UserBean> _result = this.getUsers();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
case TRANSACTION_clearUser: {
data.enforceInterface(descriptor);
this.clearUser();
reply.writeNoException();
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}

private static class Proxy implements com.sjl.exercise.ICustomAidlInterface {
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 java.lang.String getCurrentTime() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
//⑤
mRemote.transact(Stub.TRANSACTION_getCurrentTime, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

@Override
public void insertUser(com.sjl.exercise.bean.UserBean userBean) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((userBean != null)) {
_data.writeInt(1);
userBean.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_insertUser, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}

@Override
public java.util.List<com.sjl.exercise.bean.UserBean> getUsers() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<com.sjl.exercise.bean.UserBean> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getUsers, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArrayList(com.sjl.exercise.bean.UserBean.CREATOR);
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

@Override
public void clearUser() 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_clearUser, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
//②
static final int TRANSACTION_getCurrentTime = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_insertUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_getUsers = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_clearUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
}
//①
public java.lang.String getCurrentTime() throws android.os.RemoteException;

public void insertUser(com.sjl.exercise.bean.UserBean userBean) throws android.os.RemoteException;

public java.util.List<com.sjl.exercise.bean.UserBean> getUsers() throws android.os.RemoteException;

public void clearUser() throws android.os.RemoteException;
}
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
ICustomAidlInterface类最下面的①就是对应aidl文件里声明的几个方法,②所在声明了对应方法的int值,在抽象方法Stub#onTransact方法中可以看到③处正是用②中声明的int值区分调用的对应方法的。

public interface ICustomAidlInterface extends android.os.IInterface {

public static abstract class Stub extends android.os.Binder implements com.sjl.exercise.ICustomAidlInterface {
private static final java.lang.String DESCRIPTOR = "com.sjl.exercise.ICustomAidlInterface";

...
@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_getCurrentTime: {
data.enforceInterface(descriptor);
java.lang.String _result = this.getCurrentTime();
reply.writeNoException();
reply.writeString(_result);
return true;
}
case TRANSACTION_insertUser: {
data.enforceInterface(descriptor);
com.sjl.exercise.bean.UserBean _arg0;
if ((0 != data.readInt())) {
_arg0 = com.sjl.exercise.bean.UserBean.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
this.insertUser(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getUsers: {
data.enforceInterface(descriptor);
java.util.List<com.sjl.exercise.bean.UserBean> _result = this.getUsers();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
case TRANSACTION_clearUser: {
data.enforceInterface(descriptor);
this.clearUser();
reply.writeNoException();
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}

private static class Proxy implements com.sjl.exercise.ICustomAidlInterface {
...
//②
static final int TRANSACTION_getCurrentTime = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_insertUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_getUsers = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_clearUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
}
//①
public java.lang.String getCurrentTime() throws android.os.RemoteException;

public void insertUser(com.sjl.exercise.bean.UserBean userBean) throws android.os.RemoteException;

public java.util.List<com.sjl.exercise.bean.UserBean> getUsers() throws android.os.RemoteException;

public void clearUser() throws android.os.RemoteException;
}
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
Stub构造函数里传入IInterface和DESCRIPTOR,客户端通过绑定服务获取到aidl接口时使用了ICustomAidlInterface.Stub.asInterface(service)方法,在静态抽象类Stub中④处Stub#asInterface方法中可以看到使用Binder#queryLocalInterface方法获取本地aidl接口,如果有则返回本地找到的aidl接口,如果没有就返回定义的Proxy代理类(queryLocalInterface方法就是比对DESCRIPTOR来确认是否返回对应的IInterface,在不同进程时无法找到对应的IInterface,只能通过代理类Proxy来进行aidl方法调用)。

public interface ICustomAidlInterface extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements com.sjl.exercise.ICustomAidlInterface {
private static final java.lang.String DESCRIPTOR = "com.sjl.exercise.ICustomAidlInterface";
...
public static com.sjl.exercise.ICustomAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
//④
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.sjl.exercise.ICustomAidlInterface))) {
return ((com.sjl.exercise.ICustomAidlInterface) iin);
}
return new com.sjl.exercise.ICustomAidlInterface.Stub.Proxy(obj);
}

private static class Proxy implements com.sjl.exercise.ICustomAidlInterface {
...
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
查看Proxy类可以看到它的IPC都是mRemote实现的,而在对应的方法中都使用了mRemote.transact方法,传入方法对应的int值、客户端传入参数data和服务端返回结果reply

private static class Proxy implements com.sjl.exercise.ICustomAidlInterface {
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 java.lang.String getCurrentTime() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
//⑤
mRemote.transact(Stub.TRANSACTION_getCurrentTime, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

}

}
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
Binder#transact代码如下,最终调用了Binder#onTransact,也就是Binder#onTransact

/**
* Default implementation rewinds the parcels and calls onTransact. On
* the remote side, transact calls into the binder to do the IPC.
*/
public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
int flags) throws RemoteException {
if (false) Log.v("Binder", "Transact: " + code + " to " + this);

if (data != null) {
data.setDataPosition(0);
}
boolean r = onTransact(code, data, reply, flags);
if (reply != null) {
reply.setDataPosition(0);
}
return r;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Binder#onTransact方法如下,通过code确定调用的对应方法,data获取传入参数,reply设置返回值

@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 TRANSACTION_insertUser: {
data.enforceInterface(descriptor);
com.sjl.exercise.bean.UserBean _arg0;
if ((0 != data.readInt())) {
_arg0 = com.sjl.exercise.bean.UserBean.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
this.insertUser(_arg0);
reply.writeNoException(http://www.my516.com);
return true;
}
case TRANSACTION_getUsers: {
data.enforceInterface(descriptor);
java.util.List<com.sjl.exercise.bean.UserBean> _result = this.getUsers();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
}
}
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
总结:
服务端:服务端返回实现IBinder接口的对象;
客户端:客户端如果在本地找到aidl实例直接转换使用,否则通过Proxy代理调用;
通讯:本地客户端强制转换可调用调用方法,其他进程客户端需要通过Proxy代理调用方法;
---------------------

【Android】进程间通信IPC——Binder的更多相关文章

  1. Android进程间通信IPC

    一.IPC的说明 IPC是Inter-Process Communication的缩写,含义为进程间通信或跨进程通信,是指两个进程之间进行数据交换的过程. IPC不是Android独有的,任何一个操作 ...

  2. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信 ...

  3. Android进程间通信(IPC)机制Binder简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6618363 在Android系统中,每一个应用 ...

  4. Android进程间通信(IPC)机制Binder简介和学习计划

    在Android系统,每个应用程序是由多个Activity和Service部件,这些Activity和Service有可能在相同的处理被执行,此外,还可以在不同的过程中进行. 然后.不是在同一个过程A ...

  5. Android进程间通信(IPC)机制Binder简要介绍和学习计划【转】

    本文转载自:http://blog.csdn.net/luoshengyang/article/details/6618363 在Android系统中,每一个应用程序都是由一些Activity和Ser ...

  6. [置顶] 深入理解android之IPC机制与Binder框架

    [android之IPC机制与Binder框架] [Binder框架.Parcel.Proxy-Stub以及AIDL] Abstract [每个平台都会有自己一套跨进程的IPC机制,让不同进程里的两个 ...

  7. IPC进程间通信 - AIDL+Binder

      原理 http://www.linuxidc.com/Linux/2012-07/66195.htm   服务端,客户端处在用户空间,而binder驱动处在内核空间. 服务器端.一个Binder服 ...

  8. Android 中基于 Binder的进程间通信

    摘要:对  Binder 工作机制进行了分析. 首先简述 Android 中 Binder 机制与传统的 Linux 进程间的通信比较,接着对基于 Binder 进程间通信的过程分析 最后结合开发实例 ...

  9. 进程间通信IPC与Binder机制原理

    1, Intent隐式意图携带数据 2, AIDL(Binder) 3, 广播BroadCast 4, 内容提供者ContentProvider 5,Messager(内部通过binder实现) 6, ...

随机推荐

  1. 怎样对Android设备进行网络抓包

    问题描写叙述: 前段时间自己的app訪问server的url总是会出现间接性失败的问题,于是和server的同事开了个会.提出了他们server存在的这个bug,我的同事自然说自己的server没问题 ...

  2. CSS经典布局之弹性布局

    当我们在浏览浏览器的时候,经常会放大/缩小浏览器的显示比例,或者在不同的设备上.所处的分辨率也不尽同样. 因此.我们须要学习一个新的知识:弹性盒模型. 弹性盒模型 实现项目对齐,方向,排序(即使项目大 ...

  3. CountDownTimer完整具体演示样例

    MainActivity例如以下: package cc.cv; import android.os.Bundle; import android.os.CountDownTimer; import ...

  4. 并行运维工具pssh的安装及实战应用

    并行运维工具pssh的安装及实战应用 - CSDN博客 https://blog.csdn.net/field_yang/article/details/68066468

  5. POJ2449 Remmarguts' Date 第K短路

    POJ2449 比较裸的K短路问题 K短路听起来高大上 实际思路并不复杂 首先对终点t到其他所有点求最短路 即为dist[] 然后由起点s 根据当前走过的距离+dist[]进行A*搜索 第k次到达t即 ...

  6. SQL service

    依赖关系解决 ============================================================================================= ...

  7. 2-1 创建第一个Vue实例

    https://cn.vuejs.org/ 生产版本是经过压缩后的版本,它里面把一些没用的警告的代码删除掉了所以它会更精悍一些. 直接引入CDN的网址我们就可以使用Vuejs了.使用生产版本或者CDN ...

  8. akka设计模式系列-actor锚定

    actor锚定模式是指使用actorSelection对acor进行锚定的设计模式,也可以说是一个对actor的引用技巧.在某些情况下,我们可能需要能够根据Actor的path锚定对应的实例.简单来说 ...

  9. Centos 7 安装google 浏览器(yum 方式)

    过程: 1  vim /etc/yum/repo.s/google_chrome.repo 2 添加如下内容: [google-chrome] name=google-chrome          ...

  10. $luogu2375[NOI2014]$

    \(problem\) 其中,\(next[i],next[next[i]],next[next[next[i]]]......\)都是这个前缀串i的公共前后缀,而且只有它们是公共前后缀 那么,我们其 ...