使用 Messenger
Messenger 可以翻译成信使,顾明思议,通过它可以实现在不同的进程中传递 Message 对象,在Message中放入我们需要传递的数据,就可以轻松地实现数据的进程间传递了。Messenger 是一种轻量级的 IPC 方案,它的底层实现是 AIDL,为什么这么说了,我们大致的看一下 Messenger 这个类的构造方法就明白了。下面是 Messenger 的 2 个构造方法,从构造方法的实现上我们可以明显看出 AIDL 的痕迹,不管是 IMessenger 还是 Stub.asInterface,这种使用方法都表明它的底层是 AIDL。
使用 Messenger 分为 2 个步骤,服务端和客服端,下面请看代码理解也许比较容易点。
1.创建服务端的 Messenger
public class MessengerService extends Service { //定义一个 TAG private static String TAG = "MessengerService"; //实例化一个Messenger对象 private final Messenger mMessenger = new Messenger(new ReceiveLocalMessage()); //实例化一个 handle 用于接收客服端发送到服务端的消息 private static class ReceiveLocalMessage extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MyConstants.MSG_FROM_CLIENT: String yk = msg.getData().getString("yk"); Log.i(TAG, "收到客服端发送过来的消息---" + yk); //拿到客服端的信使 Messenger localMessenger = msg.replyTo; Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE); Bundle bundle = new Bundle(); bundle.putString("reply", "恩 好的,你的愿望在 2018年所有都会实现。"); relpyMessage.setData(bundle); try { localMessenger.send(relpyMessage); } catch (RemoteException e) { e.printStackTrace(); } break; } super.handleMessage(msg); } } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate---开启了 MessengerService 服务"); } @Nullable @Override public IBinder onBind(Intent intent) { //将 Messenger 对象返回 return mMessenger.getBinder(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); } }
2.创建客服端的 Messenger
public class MessengerActivity extends Activity { static TextView tvShowMessengerInfo; private static String TAG = "MessengerActivity"; //创建一个本地的Messenger private final Messenger mLocalMessenger = new Messenger(new MyLocalHandle()); //创建一个接收服务端信息的 Handle private static class MyLocalHandle extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MyConstants.MSG_FROM_SERVICE: Log.i(TAG, "receive msg from Service:" + msg.getData().getString("reply")); showText("收到客服端的回信...-----"+msg.getData().getString("reply")); break; } } } private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { showText("连接成功..."); mServiceMessenger = new Messenger(iBinder); showText("拿到服务端对象..."); Message message = Message.obtain(null, MyConstants.MSG_FROM_CLIENT); Bundle bundle = new Bundle(); bundle.putString("yk", "Hello Service 我要许一个愿望!"); message.setData(bundle); message.replyTo = mLocalMessenger; try { mServiceMessenger.send(message); showText("客服端发送一个消息..."+"-------Hello Service 我要许一个愿望!\""); } catch (RemoteException e) { Log.e(TAG, e.getMessage()); } } @Override public void onServiceDisconnected(ComponentName componentName) { showText("连接失败..."); } }; private static StringBuilder sp; private Messenger mServiceMessenger; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_messenger); tvShowMessengerInfo = findViewById(R.id.tv_showMessengerInfo); findViewById(R.id.btn_startMessenger).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startMessenger(); } }); } /** * 开始建立连接 */ public void startMessenger() { if (sp != null) sp = null; sp = new StringBuilder(); showText("准备链接..."); Intent intent = new Intent(); intent.setPackage(getPackageName()); intent.setAction("com.yk.MessengerService.launch"); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); showText("开始链接..."); } private static void showText(String str) { sp.append(str); sp.append("\r\n"); tvShowMessengerInfo.setText(sp.toString()); } }
3.清单文件中配置
<activity android:name=".messenger.MessengerActivity"> <intent-filter > <action android:name="android.intent.action.MAIN"></action> <category android:name="android.intent.category.LAUNCHER"></category> </intent-filter> </activity> <service android:name=".messenger.MessengerService" android:exported="true" android:enabled="true" android:process=":remote"> <intent-filter> <action android:name="com.yk.MessengerService.launch" /> </intent-filter> </service>
4.运行结果
Messenger 就是这么简单,相信小伙伴们都学会了吧,期待下一篇 Android 进程间通信之 AIDL 吧!