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:

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

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

public class BService extends Service {    Messenger messenger = new Messenger(new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);        }    });    @Override    public IBinder onBind(Intent intent) {        Log.e("kk", "绑定成功!");        return messenger.getBinder();    }}

这里我们使用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类:

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

public class BService extends Service {    Messenger messenger = new Messenger(new Handler() {        @Override        public void handleMessage(Message msg) {            Log.e("kk", msg.getData().getString("data"));            Message message = Message.obtain();            Bundle bundle = new Bundle();            bundle.putString("data","你要说什么?");            message.setData(bundle);            try {                msg.replyTo.send(message);            } catch (RemoteException e) {                e.printStackTrace();            }            super.handleMessage(msg);        }    });    @Override    public IBinder onBind(Intent intent) {        Log.e("kk", "绑定成功!");        return messenger.getBinder();    }}

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

public class MainActivity extends AppCompatActivity {    Messenger messenger;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ServiceConnection serviceConnection = new ServiceConnection() {            @Override            public void onServiceConnected(ComponentName name, IBinder service) {                messenger = new Messenger(service);            }            @Override            public void onServiceDisconnected(ComponentName name) {                Log.e("kk", "链接断开!");            }        };        Intent intent = new Intent();        intent.setComponent(new ComponentName("com.example.leixinxue.b", "com.example.leixinxue.b.BService"));        bindService(intent, serviceConnection, BIND_AUTO_CREATE);    }    public void sendMessageToB(View view) {        Message message = Message.obtain(null, 1);        message.replyTo = replyMessenger;        Bundle bundle = new Bundle();        bundle.putString("data", "我要和B说话!");        message.setData(bundle);        try {            messenger.send(message);        } catch (RemoteException e) {            e.printStackTrace();        }    }    Messenger replyMessenger = new Messenger(new Handler() {        @Override        public void handleMessage(Message msg) {            Log.e("kk", msg.getData().getString("data"));            super.handleMessage(msg);        }    });}
A类的布局文件:

<?xml version="1.0" encoding="utf-8"?>    


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


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



总结:

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

资源下载:
点击打开链接

更多相关文章

  1. 如何将打开res raw目录中的数据库文件?
  2. Android蓝牙设备的检测
  3. [置顶] Android(安卓)Handler Message Looper机制原理
  4. 安卓动画
  5. Android(安卓)四大组件——Service 生命周期
  6. Android(安卓)极光推送快速接入
  7. http 请求时间
  8. android Toast显示消息的几种方法
  9. Android(安卓)MVVM框架 DataBinding

随机推荐

  1. Android学习笔记之mainfest文件中android
  2. android中获取当前程序路径
  3. Android(安卓)混淆打包
  4. Android中ListView中显示图片和文本
  5. Android(安卓)P SystemUI之StatusBar加载
  6. Android内核源码交叉编译
  7. Android中丰富多彩的onTouch事件
  8. android > 禁止横竖屏切换
  9. android布局ui
  10. 四、 Android之手机屏幕朝向