Android Messenger初探
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初探相关推荐
- 十九、Android Activity初探
原文:十九.Android Activity初探 Activity是一个应用中的组件,它为用户提供一个可视的界面,方便用户操作,比如说拔打电话.照相.发邮件或者是浏览地图等.每个activity会提供 ...
- Android Activity初探
原地址:Android Activity初探 Activity是一个应用中的组件,它为用户提供一个可视的界面,方便用户操作,比如说拔打电话.照相.发邮件或者是浏览地图等.每个activity会提供一个 ...
- android插件框架机制的选择,Android插件开发初探——基础篇
Android插件开发初探 对于Android的插件化其实已经讨论已久了,但是市面上还没有非常靠谱成熟的插件框架供我们使用.这里我们就尝试性的对比一下Java中,我们使用插件化该是一个怎么样的流程,且 ...
- 使用WebRTC开发Android Messenger:第3部分
这是一个由三部分组成的系列文章,内容涉及:利用WebRTC中的BUG和利用Messenger应用程序.本系列文章重点阐述了当应用程序不能应用于WebRTC补丁程序以及通信和安全问题通知中断时可能出问题 ...
- 使用WebRTC开发Android Messenger:第2部分
这是一个由三部分组成的系列文章,内容涉及:利用WebRTC中的BUG和利用Messenger应用程序.本系列文章重点阐述了当应用程序不能应用于WebRTC补丁程序以及通信和安全问题通知中断时可能出问题 ...
- Android资源初探(一) 资源打包
Android中的资源也是一块比较重要的知识,平时工作中除了简单的使用context.getResouce().getColor(R.id.xxx)之外,我们也更想了解背后的原理.接下来的系列文章从资 ...
- android Messenger 用法,demo,helloworld
如果你觉得写aidl比较麻烦,android还简单封装了一个 Messenger api,可以进行简单的跨进程通信,不过我干android这么多年,从来没有见过有哪个项目用过这玩意儿,因为太麻烦,还不 ...
- Android插件开发初探——分析篇
承接上文 Android插件开发初探--基础篇 http://blog.csdn.net/yzzst/article/details/45582315 我们通过使用DexClassLoader能够将c ...
- 使用WebRTC开发Android Messenger:第1部分
这是一个由三部分组成的系列文章,内容涉及:利用WebRTC中的BUG和利用Messenger应用程序.本系列文章重点阐述了当应用程序不能应用于WebRTC补丁程序以及通信和安全问题通知中断时可能出问题 ...
最新文章
- [力扣] 304. 二维区域和检索 - 矩阵不可变
- B+树索引和哈希索引的区别——我在想全文搜索引擎为啥不用hash索引而非得使用B+呢?...
- 矩阵特征值与行列式、迹的关系
- 模拟投掷硬币100次
- Exp1 PC平台逆向破解(5)M
- 深度学习之Windows下安装faster-rcnn
- 字节跳动入局全网搜索;思科回应中国区裁员;IntelliJ IDEA 新版发布! | 极客头条...
- python 实例化_python中如何实例化一个对象-问答-阿里云开发者社区-阿里云
- 【十次方】十次方项目前期准备
- s3c2416 AT070TN83的LCD wince6.0驱动移植
- WP网站主页备案号存放代码
- 2022 开源之夏 | Serverless Devs 陪你“变得更强”
- win7如何设置wifi热点_Win7家庭版如何给文件夹设置密码?Win7文件夹加密方法
- linux cp 性能,linux性能监控以及优化之CPU
- 如何才能画出透亮迷人的双眼?
- 水安ABC考试多选练习题库(6)
- Chrome 内置翻译翻译失败解决
- 新一代垃圾回收器ZGC
- 三菱FX系列PLC模拟量输入AD模块的使用方法和相关编程设置详解
- C++实现分苹果问题
热门文章
- java对英文名进行排序
- Spring声明式事务管理实现及原理详解
- Hadoop学习问题4:Windows10配置hadoop后使用hadoop命令失败问题
- css星空动画,【css3进阶】less实现星空动画
- 【微信小程序开发】用户头像昵称获取规则调整 2022
- 东方梦符祭服务器维护能玩吗,东方梦符祭loading不进去怎么办 常见问题解决办法...
- mobaxterm多屏操作_MobaXterm(全能远程终端控制软件)使用方法介绍
- js怎么向上取整_JavaScript Math.ceil 方法(对数值向上取整)
- Linux命令ls -a、ls -l具体含义
- 输入IP和端口号即可访问项目