[TOC]
官方文档:[https://developer.android.com/guide/components/bound-services?hl=zh-cn](https://developer.android.com/guide/components/bound-services?hl=zh-cn)
# 使用
Messenger的使用示例如下:
Server端:
```java
// MessengerService.java
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_CLIENT:
Log.i(TAG, "handleMessage: " + msg.getData().getString("msg"));
Messenger client = msg.replyTo;
Message replyMessage = Message.obtain(null, MyConstants.MSF_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("reply", "I has receive your msg");
replyMessage.setData(bundle);
try {
client.send(replyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
```
Client端:
```java
// MessengerActivity.java
public class MessengerActivity extends AppCompatActivity {
private static final String TAG = "MessengerActivity";
private Messenger mService;
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
Message message = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg", "hello, this is client");
message.setData(data);
message.replyTo = mGetReplyMessenger;
try {
mService.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MyConstants.MSF_FROM_SERVICE:
Log.i(TAG, "handleMessage: " + msg.getData().getString("reply"));
break;
default:
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
}
}
```
# 源码分析
在Service中,根据Handler创建一个Messenger对象;然后的onBind方法中,返回的Binder对象是Messenger对象的getBinder()方法。首先从Messenger类看起:
```java
// Messenger.java
public final class Messenger implements Parcelable {
private final IMessenger mTarget;
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
public IBinder getBinder() {
return mTarget.asBinder();
}
// Parcelable序列化实现
//...
}
```
Messenger只有一个成员变量,是IMessenger类型的mTarget。构造方法有如下两种重载:
```java
// Messenger.java
// 构造方法1
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
// 构造方法2
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
```
其中,方法1适用于在Service中根据Handler构造Messenger;方法2适用于在Client中从IBinder对象生成Messenger。
## Service中实现
```java
// MessengerService.java
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
```
其中Messenger构造方法如下:
```java
// Messenger.java
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
```
调用Handler对象的getIMessenger方法来为成员变量mTarget进行赋值:
```java
// Handler.java
IMessenger mMessenger;
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
```
```java
// Handler.java#MessengerImpl
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
```
其中MessengerImpl是IMessenger.Stub的实现类。
* Handler中IMessenger类型的成员变量mMessenger,就是Messenger中的IMessenger类型的成员变量mTarget,也是整个跨进程调用中最重要的对象。
* 在Service的onBind方法中调用Messenger对象的getBinder方法获得mTarget跨进程传递。
* 在Client中,拿到IBinder对象后,根据IBinder创建出Messenger对象,当调用Messenger对象的send方法时,其实调用的就是Service中Handler的sendMessage方法。
*****
方法2中,参数是IBinder对象时,调用IMessenger.Stub的asInterface方法获得远程对象。IMessenger的AIDL文件声明如下:
```plain
// IMessenger.aidl
package android.os;
import android.os.Message;
oneway interface IMessenger {
void send(in Message msg);
}
```
## Client中实现
在Client中拿到IBinder对象后,调用Messenger的构造方法2获得Messenger对象:
```java
// Messenger.java
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
```
调用Messenger的send方法发送消息:
```java
// MessengerActivity.java(Client类)
mService.send(message);
```
```java
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
```
mTarget即IMessenger的实现为:
```java
// Handler.java#MessengerImpl
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
```
可以看到,调用了Service中的Handler的sendMessage方法。
## 总结
可以看到,Messenger对AIDL进行了封装,我们在整个使用中对于AIDL是无感的,只需要使用Messenger这个信使来进行消息的传递即可。关键思路如下:
1、Messenger类拥有一个重要的成员变量mTarget,是IMessenger类型的
2、Handler中拥有IMessenger类的默认实现,在Service中创建一个Handler,然后从Handler中获取IMessenger实现,赋值给新创建的Messenger
4、Service的onBind方法中返回的IBinder对象,其实就是Messenger的成员变量mTarget
5、Client的onServiceConnected方法中,拿到IBinder对象后,根据IBinder对象创建一个Messenger对象,IBinder对象的主要作用是初始化了Messenger类的mTarget成员变量
6、Client需要跨进程调用时,调用Client中Messenger对象的send方法,实际上是调用了mTarget的send方法,默认实现在Service的Handler中,也就是调用Handler发送消息。
- 导读
- Java知识
- Java基本程序设计结构
- 【基础知识】Java基础
- 【源码分析】Okio
- 【源码分析】深入理解i++和++i
- 【专题分析】JVM与GC
- 【面试清单】Java基本程序设计结构
- 对象与类
- 【基础知识】对象与类
- 【专题分析】Java类加载过程
- 【面试清单】对象与类
- 泛型
- 【基础知识】泛型
- 【面试清单】泛型
- 集合
- 【基础知识】集合
- 【源码分析】SparseArray
- 【面试清单】集合
- 多线程
- 【基础知识】多线程
- 【源码分析】ThreadPoolExecutor源码分析
- 【专题分析】volatile关键字
- 【面试清单】多线程
- Java新特性
- 【专题分析】Lambda表达式
- 【专题分析】注解
- 【面试清单】Java新特性
- Effective Java笔记
- Android知识
- Activity
- 【基础知识】Activity
- 【专题分析】运行时权限
- 【专题分析】使用Intent打开三方应用
- 【源码分析】Activity的工作过程
- 【面试清单】Activity
- 架构组件
- 【专题分析】MVC、MVP与MVVM
- 【专题分析】数据绑定
- 【面试清单】架构组件
- 界面
- 【专题分析】自定义View
- 【专题分析】ImageView的ScaleType属性
- 【专题分析】ConstraintLayout 使用
- 【专题分析】搞懂点九图
- 【专题分析】Adapter
- 【源码分析】LayoutInflater
- 【源码分析】ViewStub
- 【源码分析】View三大流程
- 【源码分析】触摸事件分发机制
- 【源码分析】按键事件分发机制
- 【源码分析】Android窗口机制
- 【面试清单】界面
- 动画和过渡
- 【基础知识】动画和过渡
- 【面试清单】动画和过渡
- 图片和图形
- 【专题分析】图片加载
- 【面试清单】图片和图形
- 后台任务
- 应用数据和文件
- 基于网络的内容
- 多线程与多进程
- 【基础知识】多线程与多进程
- 【源码分析】Handler
- 【源码分析】AsyncTask
- 【专题分析】Service
- 【源码分析】Parcelable
- 【专题分析】Binder
- 【源码分析】Messenger
- 【面试清单】多线程与多进程
- 应用优化
- 【专题分析】布局优化
- 【专题分析】绘制优化
- 【专题分析】内存优化
- 【专题分析】启动优化
- 【专题分析】电池优化
- 【专题分析】包大小优化
- 【面试清单】应用优化
- Android新特性
- 【专题分析】状态栏、ActionBar和导航栏
- 【专题分析】应用图标、通知栏适配
- 【专题分析】Android新版本重要变更
- 【专题分析】唯一标识符的最佳做法
- 开源库源码分析
- 【源码分析】BaseRecyclerViewAdapterHelper
- 【源码分析】ButterKnife
- 【源码分析】Dagger2
- 【源码分析】EventBus3(一)
- 【源码分析】EventBus3(二)
- 【源码分析】Glide
- 【源码分析】OkHttp
- 【源码分析】Retrofit
- 其他知识
- Flutter
- 原生开发与跨平台开发
- 整体归纳
- 状态及状态管理
- 零碎知识点
- 添加Flutter到现有应用
- Git知识
- Git命令
- .gitignore文件
- 设计模式
- 创建型模式
- 结构型模式
- 行为型模式
- RxJava
- 基础
- Linux知识
- 环境变量
- Linux命令
- ADB命令
- 算法
- 常见数据结构及实现
- 数组
- 排序算法
- 链表
- 二叉树
- 栈和队列
- 算法时间复杂度
- 常见算法思想
- 其他技术
- 正则表达式
- 编码格式
- HTTP与HTTPS
- 【面试清单】其他知识
- 开发归纳
- Android零碎问题
- 其他零碎问题
- 开发思路