1. 背景

最近在看任玉刚老师的《Android开发艺术探索》,看到了 Messenger,觉得挺有意思的,写个 Demo 练习一下,同时根据 Messenger 可以延伸到其他知识点,比如Android的Binder通信机制,AIDL等知识点,本文算是 Messenger 初探。

1.1 Messenger 介绍

首先肯定要看一下官方对于 Messenger 的介绍。

/*** 引用 Handler, 可以用其来发送 Message 信息。* 允许跨进程来实现基于信息的通讯,通过在一个进程中创建一个 Messenger 对象,并且关联一个 Handler 对象,然后将消息传递给另外一个进程。* 注意:其实现只是对 Binder 一个简单的包装,用于执行通信。这意味着从语义上来说:* 这个类不影响进程的生命周期管理,如果的进程因为任何原因离开,连接将中断,等等,你必须使用一些更高级的组件来告诉系统您的流程需要继续运行。*/
public final class Messenger implements Parcelable {private final IMessenger mTarget;/*** 创建一个指定(关联)了一个 Handler 对象的 Messenger 对象。* 通过该 Messenger 发送的任何消息都会被指定的 Handler 所接收,就像直接调用 Handler.sendMessage(Message)一样* * @param target 传入一个用于接受消息的 Handler对象。*/public Messenger(Handler target) {mTarget = target.getIMessenger();}

Messenger 译为信使,用于在不同的进程间传递 Message 信息,是 Service服务端与 Activity客户端之间通信的桥梁。

2. 简单例子Demo

简单的例子说明:首先创建一个服务端,可以让其处于额外的进程中,其次创建一个客户端,也就是我们的Activity,点击发送信息按钮后,客户端向服务端发送信息,并且服务端在接收到信息后,返回信息回给客户端。

2.1 创建服务端

创建一个服务端,取名为 MessengerService,并在清单文件中设置属性,让其处以额外的进程中,代码如下:

public class MessengerService extends Service {private static final String TAG = "MessengerService";public static final int MSG_FROM_SERVICE = 2;public static final String SERVICE_REPLY_MSG_KEY = "SERVICE_REPLY_MSG";private Messenger mMessenger = new Messenger(new MyHandler());@Overridepublic IBinder onBind(Intent intent) {return mMessenger.getBinder();}public static class MyHandler extends Handler {@Overridepublic void handleMessage(@NonNull Message msgFromClient) {super.handleMessage(msgFromClient);Bundle sendByClientBundle = msgFromClient.getData();String clientMsg = sendByClientBundle.getString(MessengerServiceTestActivity.CLIENT_SEND_MSG_KEY);Log.e(TAG, "client send message: " + clientMsg);switch (msgFromClient.what) {case MessengerServiceTestActivity.MSG_FROM_CLIENT:try {//模拟耗时4秒,服务端回应信息给客户端Thread.sleep(4000);Message replyClientMsg = new Message();replyClientMsg.what = MSG_FROM_SERVICE;Bundle bundle = new Bundle();bundle.putString(SERVICE_REPLY_MSG_KEY, "My Name is Jere");replyClientMsg.setData(bundle);//回应消息给客户端msgFromClient.replyTo.send(replyClientMsg);} catch (InterruptedException | RemoteException e) {e.printStackTrace();}break;default:break;}}}
}

在清单文件中设置该服务,并设置其 process 属性,让其处于额外的进程中,如newprocess。

<serviceandroid:name=".messenger.MessengerService"android:enabled="true"android:exported="true"android:process=":newprocess"/>

这样设置好后 MessengerService 就处在了 com.example.servicetest:newprocess 进程中。

2.2 创建客户端

创建一个客户端,取名为:MessengerServiceTestActivity,代码如下:

public class MessengerServiceTestActivity extends AppCompatActivity {private static final String TAG = "MessengerServiceTestActivity";public static final int MSG_FROM_CLIENT = 1;public static final String CLIENT_SEND_MSG_KEY = "CLIENT_SEND_MSG";private Messenger mMessenger;private boolean isBoundService;private Messenger mReplyToMessenger = new Messenger(new ServiceReplyToMessengerHandler());private ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//利用服务端返回的 IBinder,新创建一个Messenger对象mMessenger = new Messenger(service);isBoundService = true;Log.d(TAG, "onServiceConnected: ");}@Overridepublic void onServiceDisconnected(ComponentName name) {isBoundService = false;Log.d(TAG, "onServiceDisconnected: ");}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_messenger_service_test);//点击按钮,客户端向服务端发送信息,并指定了用于接收服务端返回信息的 Messenger 对象Button sendMsgBtn = findViewById(R.id.send_message_btn);sendMsgBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Message message = new Message();message.what = MSG_FROM_CLIENT;Bundle sendToServiceBundle = new Bundle();sendToServiceBundle.putString(CLIENT_SEND_MSG_KEY, "Hi! What's your name!");message.setData(sendToServiceBundle);//指定用于接收服务端返回信息的 Messengermessage.replyTo = mReplyToMessenger;try {//通过调用 Messenger 中的 send() 方法,将消息发送给服务端mMessenger.send(message);} catch (RemoteException e) {e.printStackTrace();}}});}@Overrideprotected void onStart() {super.onStart();//绑定服务Intent intent = new Intent(this, MessengerService.class);bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);}@Overrideprotected void onStop() {super.onStop();//如果绑定了服务,则解绑服务if (isBoundService) {unbindService(serviceConnection);isBoundService = false;}}public static class ServiceReplyToMessengerHandler extends Handler {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case MessengerService.MSG_FROM_SERVICE:Bundle serviceReplyBundle = msg.getData();String name = serviceReplyBundle.getString(MessengerService.SERVICE_REPLY_MSG_KEY);Log.e(TAG, "receiver service message info: " + name);break;default:break;}}}
}

同时看一下其在清单文件中的配置:

<activity android:name=".messenger.MessengerServiceTestActivity"/>

没有额外的为客户端设置进程属性,这是客户端位于 com.example.servicetest 进程中。

2.3 测试

点击按钮后,客户端向服务端发送 “Hi! What’s your name!”,服务端在接收到信息后,返回给客户端 “My Name is Jere”,注意看 LOG 信息,其处于的进程是不一样的。

//服务端接收到客户端发送过来的信息
com.example.servicetest:newprocess E/MessengerService: client send message: Hi! What's your name!
//客户端接收到服务端返回的信息
com.example.servicetest E/MessengerServiceTestActivity: receiver service message info: My Name is Jere

End~
本文只是简单的对 Messenger 进行初探~

Android Messenger初探相关推荐

  1. 十九、Android Activity初探

    原文:十九.Android Activity初探 Activity是一个应用中的组件,它为用户提供一个可视的界面,方便用户操作,比如说拔打电话.照相.发邮件或者是浏览地图等.每个activity会提供 ...

  2. Android Activity初探

    原地址:Android Activity初探 Activity是一个应用中的组件,它为用户提供一个可视的界面,方便用户操作,比如说拔打电话.照相.发邮件或者是浏览地图等.每个activity会提供一个 ...

  3. android插件框架机制的选择,Android插件开发初探——基础篇

    Android插件开发初探 对于Android的插件化其实已经讨论已久了,但是市面上还没有非常靠谱成熟的插件框架供我们使用.这里我们就尝试性的对比一下Java中,我们使用插件化该是一个怎么样的流程,且 ...

  4. 使用WebRTC开发Android Messenger:第3部分

    这是一个由三部分组成的系列文章,内容涉及:利用WebRTC中的BUG和利用Messenger应用程序.本系列文章重点阐述了当应用程序不能应用于WebRTC补丁程序以及通信和安全问题通知中断时可能出问题 ...

  5. 使用WebRTC开发Android Messenger:第2部分

    这是一个由三部分组成的系列文章,内容涉及:利用WebRTC中的BUG和利用Messenger应用程序.本系列文章重点阐述了当应用程序不能应用于WebRTC补丁程序以及通信和安全问题通知中断时可能出问题 ...

  6. Android资源初探(一) 资源打包

    Android中的资源也是一块比较重要的知识,平时工作中除了简单的使用context.getResouce().getColor(R.id.xxx)之外,我们也更想了解背后的原理.接下来的系列文章从资 ...

  7. android Messenger 用法,demo,helloworld

    如果你觉得写aidl比较麻烦,android还简单封装了一个 Messenger api,可以进行简单的跨进程通信,不过我干android这么多年,从来没有见过有哪个项目用过这玩意儿,因为太麻烦,还不 ...

  8. Android插件开发初探——分析篇

    承接上文 Android插件开发初探--基础篇 http://blog.csdn.net/yzzst/article/details/45582315 我们通过使用DexClassLoader能够将c ...

  9. 使用WebRTC开发Android Messenger:第1部分

    这是一个由三部分组成的系列文章,内容涉及:利用WebRTC中的BUG和利用Messenger应用程序.本系列文章重点阐述了当应用程序不能应用于WebRTC补丁程序以及通信和安全问题通知中断时可能出问题 ...

最新文章

  1. [力扣] 304. 二维区域和检索 - 矩阵不可变
  2. B+树索引和哈希索引的区别——我在想全文搜索引擎为啥不用hash索引而非得使用B+呢?...
  3. 矩阵特征值与行列式、迹的关系
  4. 模拟投掷硬币100次
  5. Exp1 PC平台逆向破解(5)M
  6. 深度学习之Windows下安装faster-rcnn
  7. 字节跳动入局全网搜索;思科回应中国区裁员;IntelliJ IDEA 新版发布! | 极客头条...
  8. python 实例化_python中如何实例化一个对象-问答-阿里云开发者社区-阿里云
  9. 【十次方】十次方项目前期准备
  10. s3c2416 AT070TN83的LCD wince6.0驱动移植
  11. WP网站主页备案号存放代码
  12. 2022 开源之夏 | Serverless Devs 陪你“变得更强”
  13. win7如何设置wifi热点_Win7家庭版如何给文件夹设置密码?Win7文件夹加密方法
  14. linux cp 性能,linux性能监控以及优化之CPU
  15. 如何才能画出透亮迷人的双眼?
  16. 水安ABC考试多选练习题库(6)
  17. Chrome 内置翻译翻译失败解决
  18. 新一代垃圾回收器ZGC
  19. 三菱FX系列PLC模拟量输入AD模块的使用方法和相关编程设置详解
  20. C++实现分苹果问题

热门文章

  1. java对英文名进行排序
  2. Spring声明式事务管理实现及原理详解
  3. Hadoop学习问题4:Windows10配置hadoop后使用hadoop命令失败问题
  4. css星空动画,【css3进阶】less实现星空动画
  5. 【微信小程序开发】用户头像昵称获取规则调整 2022
  6. 东方梦符祭服务器维护能玩吗,东方梦符祭loading不进去怎么办 常见问题解决办法...
  7. mobaxterm多屏操作_MobaXterm(全能远程终端控制软件)使用方法介绍
  8. js怎么向上取整_JavaScript Math.ceil 方法(对数值向上取整)
  9. Linux命令ls -a、ls -l具体含义
  10. 输入IP和端口号即可访问项目