网上关于Messenger的文章很多,但是通俗易懂的少,这里简单介绍一下我的理解。
一言以蔽之即:
消息Message 可以 绑定 信使Messenger
触发流程:
A 收到 一个消息Messge,里面有个信使 Messenger_B,
那么这时候 A 就可以通过 Messenger_B.send(msg); 将消息msg发给 B,
B 内直接回调 Messenger_B 所绑定的 handler。
举例:
应用A Client 端
应用 B Service 端
假设A 已经拿到 B 的 Messenger,即 serviceMessenger 。
具体如何拿到后面补充。
Client端代码
Message message = Message.obtain(); Bundle bundle = new Bundle(); bundle.putString("电影", "科幻电影"); message.setData(bundle); message.what = 1; //最重要的一步,将clientMessenger绑定在消息内,发给服务端,这样服务端可以用 clientMessenger 再发送消息回来。 message.replyTo = clientMessenger; try { serviceMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); }记住这里最重要的一步就是 设置 replyTo,这样当服务端收到你的消息后,可以再使用你的信使把消息给你发回来
Service端代码
private static class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: Bundle data = msg.getData(); String s = data.getString("电影","辣鸡"); Log.i("服务端", s); Message message = new Message(); Bundle bundle = new Bundle(); bundle.putString("晚餐","服务端给客户端发来了晚餐消息"); message.what = 2; message.setData(bundle); try { //看这里,最重要的一步,使用消息msg内所附带的信使,这里也就是 clientMessenger,再把消息发送回去 msg.replyTo.send(message); } catch (RemoteException e) { e.printStackTrace(); } break; default: super.handleMessage(msg); } } }结果
客户端绑定服务端,拿到服务端信使,发送了一条消息 ClientMsg 过去,消息内数据为 “科幻电影”
服务端拿到了数据,并使用 ClientMsg 内 所绑定的信使(即客户端的信使),再发送一条消息回去,信息内容为 “服务端给客户端发来了晚餐消息”。
01-12 18:17:23.461 14704-14704/com.example.yanlong.client I/客户端: 绑定成功
01-12 18:17:23.461 14704-14704/com.example.yanlong.client I/客户端: 服务端给客户端发来了晚餐消息
01-12 18:17:23.461 14500-14500/com.example.yanlong.service I/服务端: 开始创建 onCreate
01-12 18:17:23.461 14500-14500/com.example.yanlong.service I/服务端: onBind
01-12 18:17:23.461 14500-14500/com.example.yanlong.service I/服务端: 科幻电影
如何在客户端拿到服务端的信使 Messenger
很简单,就像平常开启服务差不多。这里我将代码贴出。
代码里没有去操作关闭服务,以及使用boolean 判断是否绑定成功。各位后期增加。
Client
package com.example.yanlong.client; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private Messenger serviceMessenger; private static class ClientHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case 2: Bundle data = msg.getData(); String c = data.getString("晚餐"); Log.i("客户端", "" + c); break; default: super.handleMessage(msg); } } } private Messenger clientMessenger = new Messenger(new ClientHandler()); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = (TextView) findViewById(R.id.textView); textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { bindService(); } }); } private ServiceConnection sc = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i("客户端", "绑定成功"); //重要,这里是获取服务端信使 serviceMessenger = new Messenger(service); Message message = Message.obtain(); Bundle bundle = new Bundle(); bundle.putString("电影", "科幻电影"); message.setData(bundle); message.what = 1; //最重要的一步,将clientMessenger绑定在消息内,发给服务端,这样服务端可以用 clientMessenger 再发送消息回来。 message.replyTo = clientMessenger; try { serviceMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; private void bindService() { Intent intent = new Intent(); intent.setPackage("com.example.yanlong.service"); intent.setAction("comxxxxx"); bindService(intent, sc, BIND_AUTO_CREATE); } }
Service端
package com.example.yanlong.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.annotation.Nullable; import android.util.Log; /** * 项目名称:Service * 类名称 :com.example.yanlong.service * 作者 :高延荣 * 创建时间:2018/1/12 * 类描述 : */ public class MyService extends Service { private static class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: Bundle data = msg.getData(); String s = data.getString("电影","辣鸡"); Log.i("服务端", s); Message message = new Message(); Bundle bundle = new Bundle(); bundle.putString("晚餐","服务端给客户端发来了晚餐消息"); message.what = 2; message.setData(bundle); try { //看这里,最重要的一步,使用消息msg内所附带的信使,这里也就是 clientMessenger,再把消息发送回去 msg.replyTo.send(message); } catch (RemoteException e) { e.printStackTrace(); } break; default: super.handleMessage(msg); } } } Messenger messenger = new Messenger(new MyHandler()); @Override public void onCreate() { Log.i("服务端", "开始创建 onCreate"); super.onCreate(); } @Nullable @Override public IBinder onBind(Intent intent) { Log.i("服务端", "onBind"); return messenger.getBinder(); } private class MyBinder extends Binder { public void doSome() { Log.i("服务端", "已经接收到您的服务请求"); } } }服务端清单配置
<service android:name=".MyService"> <intent-filter> <action android:name="comxxxxx" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>