当前位置:   article > 正文

Android 使用Messenger实现跨app通信_两个app发消息

两个app发消息

Android中使用跨进程通信有以下几种方式:文件、广播、aidl、messenger,今天要讲的是使用messenger来实现跨app通信也就是在两个不同的app中实现双向通信。其实Messenger底层也是使用aidl的方式来实现的,只不过其使用handler来处理消息,因为handler是线程安全的,所以Messenger也是线程安全的,自然Messenger只能处理单线程的问题,如果要使用多线程就该使用aidl的方式实现。

我们来说下通信的大致流程:首先我们创建两个应用A、B,在应用B中创建一个Service取名:BService,然后我们在A中通过bindService来绑定BService,这样之后两个App就实现了破冰之旅。

上面的情况只是说明了大体的流程,具体如何实现绑定远程的BService和如何在BService中来回复A应用,这里我详细的说下。我们知道bindService()方法中需要三个参数,

bindService(intent, serviceConnection, BIND_AUTO_CREATE);

第一个为Intent对象,第二个为ServiceConnection,最后一个参数为如何去绑定,一般都是写的这个值。这些相信大家都非常的清楚了,和平时的绑定服务是一样的,我们做的也是一样的,不同的是在ServiceConnection中,我们这样处理返回的IBinder:

  1. ServiceConnection serviceConnection = new ServiceConnection() {
  2. @Override
  3. public void onServiceConnected(ComponentName name, IBinder service) {
  4. messenger = new Messenger(service);
  5. }
  6. @Override
  7. public void onServiceDisconnected(ComponentName name) {
  8. Log.e("kk", "链接断开!");
  9. }
  10. };
我们看到,这里我们使用IBinder来创建Messenger对象,然后我们就可以使用这个mesender来像远程的服务发送数据:

  1. Message message = Message.obtain(null, 1);
  2. Bundle bundle = new Bundle();
  3. bundle.putString("data", "我要和B说话!");
  4. message.setData(bundle);
  5. try {
  6. messenger.send(message);//发送数据
  7. } catch (RemoteException e) {
  8. e.printStackTrace();
  9. }
这里我们使用messenger.send()方法来发送数据。下面我们来看看BService中的代码:

  1. public class BService extends Service {
  2. Messenger messenger = new Messenger(new Handler() {
  3. @Override
  4. public void handleMessage(Message msg) {
  5. super.handleMessage(msg);
  6. }
  7. });
  8. @Override
  9. public IBinder onBind(Intent intent) {
  10. Log.e("kk", "绑定成功!");
  11. return messenger.getBinder();
  12. }
  13. }

这里我们使用Messenger.getBinder()方法返回IBinder,和A中的代码做比较我们就会发现,这里使用messenger的getBinder()返回IBinder,A中又通过返回的IBinder创建了一个Messenger对象,所以他们都是用的同一个IBinder对象,这样通过Messenger发送的消息自然是会在B中的Messenger创建时候的Handler里面来处理了,这样就实现了A像B应用发送消息。

那么B中如何像A发送消息呢???我们知道 Message中有属性:replyTo,该属性是一个Messenger类别的,如果我们在A类中将该属性赋值给一个Messenger对象,然后在B类中获取到该对象然后通过其发送消息,这样消息自然就会在A类中的Messenger中来处理,这样就实现了B类向A类发送消息,到这里我们就实现了双向的通信,具体修改后的代码这里我贴出来,首先是A类:

  1. message.replyTo = replyMessenger;
  2. essenger replyMessenger = new Messenger(new Handler() {
  3. @Override
  4. public void handleMessage(Message msg) {
  5. Log.e("kk", msg.getData().getString("data"));
  6. super.handleMessage(msg);
  7. }
  8. });
然后是在B类中:

  1. public class BService extends Service {
  2. Messenger messenger = new Messenger(new Handler() {
  3. @Override
  4. public void handleMessage(Message msg) {
  5. Log.e("kk", msg.getData().getString("data"));
  6. Message message = Message.obtain();
  7. Bundle bundle = new Bundle();
  8. bundle.putString("data","你要说什么?");
  9. message.setData(bundle);
  10. try {
  11. msg.replyTo.send(message);
  12. } catch (RemoteException e) {
  13. e.printStackTrace();
  14. }
  15. super.handleMessage(msg);
  16. }
  17. });
  18. @Override
  19. public IBinder onBind(Intent intent) {
  20. Log.e("kk", "绑定成功!");
  21. return messenger.getBinder();
  22. }
  23. }

我再贴出A类中所有的代码:

  1. public class MainActivity extends AppCompatActivity {
  2. Messenger messenger;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. ServiceConnection serviceConnection = new ServiceConnection() {
  8. @Override
  9. public void onServiceConnected(ComponentName name, IBinder service) {
  10. messenger = new Messenger(service);
  11. }
  12. @Override
  13. public void onServiceDisconnected(ComponentName name) {
  14. Log.e("kk", "链接断开!");
  15. }
  16. };
  17. Intent intent = new Intent();
  18. intent.setComponent(new ComponentName("com.example.leixinxue.b", "com.example.leixinxue.b.BService"));
  19. bindService(intent, serviceConnection, BIND_AUTO_CREATE);
  20. }
  21. public void sendMessageToB(View view) {
  22. Message message = Message.obtain(null, 1);
  23. message.replyTo = replyMessenger;
  24. Bundle bundle = new Bundle();
  25. bundle.putString("data", "我要和B说话!");
  26. message.setData(bundle);
  27. try {
  28. messenger.send(message);
  29. } catch (RemoteException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. Messenger replyMessenger = new Messenger(new Handler() {
  34. @Override
  35. public void handleMessage(Message msg) {
  36. Log.e("kk", msg.getData().getString("data"));
  37. super.handleMessage(msg);
  38. }
  39. });
  40. }
A类的布局文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <Button
  6. android:layout_width="match_parent"
  7. android:layout_height="wrap_content"
  8. android:layout_centerInParent="true"
  9. android:onClick="sendMessageToB"
  10. android:text="发送消息!" />
  11. </RelativeLayout>


好啦,这里两个类就可以实现通信了,点击A类中的发送消息按钮就可以给B发送一条消息,B收到消息后立马回复一个消息给A。


扫描关注我的微信公众号:



总结:

两个app间通信通过Messenger其实很简单的,就是通过bindService绑定到远程的service,然后用在绑定的Serviceconnection中返回的IBinder来创建一个Messenger对象,通过Messenger的send发送消息到远程的服务,远程的服务通过Message中的属性replyTo就可以回复收到的消息,不要忘了给replyTo赋值。好了,详细我已经将的很详细了,如果你还有什么疑问,欢迎给我留言,bye~~

资源下载:
点击打开链接

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/122585
推荐阅读
相关标签
  

闽ICP备14008679号