Android进程间通信(二)- Messenger
概述
Messenger 翻译为信使,顾名思义,就是可以在不同进程之间传递Message对象。它是一种基于AIDL的轻量型的IPC方案。
定义
源码里面Messenger的定义比较简单,只是实现了Parcelable接口,之外提供了构造和发送方法。同时它也是一个final类。
public final class Messenger implements Parcelable {
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
...
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
}
从他的两个构造方法,其实可以看出有着AIDL的痕迹,比如“getIMessenger”、“IMessenger.Stub.”。所以可以看作是对AIDL的简单封装。
接着跟踪 getIMessenger(),发现
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
可以看到getIMessenger方法返回的是MessengerImpl对象,而MessengerImpl是Handle的一个内部类,并且继承了IMessenger.Stub,实现了其send()方法。看到这,想必大家看出来了IMessenger.Stub这种形式就和AIDL使用方式很像,所以印证了之前的说法。Messenger的底层的确是AIDL。
MessengerImpl 类的实现可以看到,客户端msg通过binder方式传递过来,而当前进程的Handler将其加入自己的messagequeue并处理它。 PS: IMessenger类位于:
frameworks/base/core/Java/android/os/IMessenger.aidl
使用
服务端
public class ServerService extends Service {
private static final String TAG = "ServerService";
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private final Messenger mMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 1:
Log.i(TAG,"Message data = "+msg.getData().getString("data"));
break;
default:
super.handleMessage(msg);
}
}
}
}
分3步:
- 实现静态内部类继承Handler
- 新建Messenger对象
- Onbind方法返回Messenger.getBinder()
为了实现进程间通信,于是在Manifast文件注册可以指定进程号, 这样就实现了和主进程不同进程。
<service
android:name=".ServerService"
android:process=":remote"></service>
就这么简单。剩下的就是等着客户端来撩骚你了。
客户端
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Messenger mService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, ServerService.class);
bindService(intent,mConnect, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConnect = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG,"onServiceConnected ");
mService = new Messenger(service);
Message mag = Message.obtain(null, 1);
Bundle data = new Bundle();
data.putString("data"," Hello , i come from client ");
mag.setData(data);
try {
mService.send(mag);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
};
@Override
protected void onDestroy() {
unbindService(mConnect);
super.onDestroy();
}
}
为了对称也分3步:
- 绑定对应的service – bindService
- 初始化ServiceConnection 对象
- 拿到服务器返回的IBinder对象,通过这个初始化Messenger对象,就可以发送消息
运行结果
xxxx.messagertest I/MainActivity: onServiceConnected
xxxx.messagertest:remote I/ServerService: Message.what = Hello , i come from client
可以看到service收到了Activity的消息,并且service进程是xxxx.messagertest:remote,而Activity在xxxx.messagertest。说明进程间通讯成功实现!!
扩展双向通信
服务端
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 1:
Log.i(TAG,"Message.what = "+msg.getData().getString("data"));
Messenger client = msg.replyTo; //主要添加这句
Message reply = Message.obtain(null ,2);
Bundle data = new Bundle();
data.putString("reply","ok , i get it!");
reply.setData(data);
try {
client.send(reply);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
客户端
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG,"onServiceConnected ");
mService = new Messenger(service);
Message mag = Message.obtain(null,1);
Bundle data = new Bundle();
data.putString("data","Hello , i come from client");
mag.replyTo = mClientMessenger; //这句需要添加
mag.setData(data);
try {
mService.send(mag);
} catch (RemoteException e) {
e.printStackTrace();
}
}
...
private Messenger mClientMessenger = new Messenger(new ClientHander());
private static class ClientHander extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 2:
Log.i(TAG,"Message.what = "+msg.getData().getString("reply"));
break;
default:
super.handleMessage(msg);
}
}
}
总结一下,其实就是客户端需要指定Messenger的replyto,其他类似于之前的服务端实现。而服务器端只需要拿到replyTo对象就可以向客户端发送消息。
运行结果
I/ServerService: Message.what = Hello , i come from client
I/MainActivity: Message.what = ok , i get it!
相关文章
- android 混淆规则作用,Android代码混淆详解
- mac 电脑android环境变量设置,mac上Android环境变量配置[通俗易懂]
- android-短信验证功能,Android实现获取短信验证码的功能以及自定义GUI短信验证详解…
- 安卓broadcastreceiver_Android手电筒原理
- android登录注册跳转的代码_Android开发代码
- Android进程间通信之一:Binder机制学习
- android进程间通信方式有哪几种_安卓进程间通信
- android进程间通信的方式_Android进程注入
- 【Android 逆向】Android 权限 ( 查看内存信息 | 查看 CPU 信息 | 查看电池信息 | 查看账户信息 | 查看 Activity 信息 | 查看 Package 信息 )
- 【Android 逆向】Android 进程简介 ( Android 应用启动流程 )
- 【Android 逆向】代码调试器开发 ( ptrace 函数 | 读取进程内存数据 )
- 【Android 逆向】Android 进程注入工具开发 ( 编译注入工具 | 编译结果文件说明 | 注入过程说明 )
- 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 一 | mmap 函数简介 )
- Android File Transfer for mac(强大的安卓文件传输工具)
- Android编程开发基本规范和原则详解手机开发
- Android Proximity Sensor近距离传感器P-Sensor详解手机开发
- Android开启闪光灯做手电筒的详解