android:使用Messenger进行进程间通信(二)
//继续完善音乐播放器demo
相关文章:
android:使用Messenger进行进程间通信(一):http://www.cnblogs.com/happyhacking/p/5318418.html
android:使用RemoteView自定义Notification:http://www.cnblogs.com/happyhacking/p/5318529.html
activity => service => notification
在添加了Notification之后,出现一个问题,即通过activity和notification都可以实现对service中方法的调用,
然而目前两者并不能同步.由于之前已经实现了从activity到service的进程间通信,所以当在activtiy中进行操作时,
相应的在service中使用handler更新notification的内容即可.
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
mActivityMessenger = msg.replyTo;
switch (msg.what) {
case 0:
mMediaPlayer.stop();
i = msg.arg1;
mMediaPlayer = MediaPlayer.create(MusicService.this, mMusicDatas.get(i).getSrc());
if(isPlaying) {
mMediaPlayer.start();
}
//更新notification显示的内容
mRemoteViews.setTextViewText(R.id.music_name, mMusicDatas.get(i).getName());
mRemoteViews.setTextViewText(R.id.singer_name, mMusicDatas.get(i).getSinger());
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
break;
case 1:
if(msg.arg1==1){
isPlaying =false;
mMediaPlayer.pause();
//更新notification显示的内容
mRemoteViews.setImageViewResource(R.id.btn_play, R.drawable.note_btn_play);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
} else {
isPlaying = true;
i = msg.arg2;
mMediaPlayer = MediaPlayer.create(MusicService.this, mMusicDatas.get(i).getSrc());
mMediaPlayer.start();
//更新notification显示的内容
mRemoteViews.setImageViewResource(R.id.btn_play, R.drawable.note_btn_pause);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
break;
default:
break;
}
}
}
notification => service => activity
在谷歌的官方文档中有以下描述:
If you want the service to respond, then you need to also create a Messenger in the client.
Then when the client receives the onServiceConnected() callback, it sends a Message to the service
that includes the client's Messenger in the replyTo parameter of the send() method.
个人理解是:
要实现service到activity的通信,需要在activity(client)也创建一个Messenger,并且在onServiceConnected()
方法中将这个messenger实例作为replyTo的参数send到service.
activity中的处理:
①创建activity自身的messenger,用来处理service发送过来的message
②在ServiceConnection实例的onServiceConnected()回调方法中将activity的messenger作为msg.replyTo的参数send给service
//创建activity自身的messenger
private Messenger mActivityMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case CODE:
mIndex = msg.arg1;
setMusicNameAndSingerName(mIndex);
if(msg.arg2 == 1) {
mPlayBtn.setBackgroundResource(R.drawable.desk_pause);
} else {
mPlayBtn.setBackgroundResource(R.drawable.desk_play);
}
}
}
});
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger = new Messenger(service);
//注意这里紧接着要send一次,目的是防止首先操作的是notification,而这时service还没有得到activity的messenger,导致service->activity的通信失败.
Message message = Message.obtain();
message.replyTo = mActivityMessenger;
try {
mMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
service中的处理
在自定义hangdler中接收activity发送过来的messenger.
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//获取client的messenger
mActivityMessenger = msg.replyTo;
switch (msg.what) {
//...
}
}
}
当notification中的点击事件发生时,调用以下方法,向activity发送msg
//service->activity
private void sendToActivity() {
Message message = Message.obtain();
message.what = MainActivity.CODE;
message.arg1 = i;
message.arg2 = (isPlaying == true)?1:2;
try {
mActivityMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
如此一来,就实现了activity和service之间的进程间的双向通信.
基本原理如下图所示:

图中:黑字实线是activity和service的绑定过程中相互发送messenger的过程.
红字虚线是进程间相互通信的过程.
需要强调的是:
在bindService()成功后,要立即将activity的messenger发送给service,否则,如果在此操作之前,操作notification,
由于此时service中还没有activity的messenger,将无法将notification的操作同步到activity中.
github地址:https://github.com/zhangbz/MusicPlayer
android:使用Messenger进行进程间通信(二)的更多相关文章
- android:使用Messenger进行进程间通信(一)
Messenger简介 Messenger和AIDL是实现进程间通信(interprocess communication)的两种方式. 实际上,Messenger的实现其实是对AIDL的封装. Me ...
- Android 基于Message的进程间通信 Messenger完全解析
一.概述 说到Android进程间通信,大家肯定能想到的是编写aidl文件,然后通过aapt生成的类方便的完成服务端,以及客户端代码的编写.如果你对这个过程不熟悉,可以查看Android aidl B ...
- 【Android】17.5 利用Messenger实现进程间通信(IPC)
分类:C#.Android.VS2015: 创建日期:2016-03-03 一.Messager类简介 本章前面曾经说过,要在Android上执行带服务的进程间通信(IPC),既可以用Messenge ...
- Android - 使用messager实现进程间通信(服务器端→客户端,客户端→服务器端双向)
之前看了一篇,然后不自己动手肯定是不行的,然后自己又写了一遍. 背景: 一般使用messenger进行进程间通信的时候,我们只能进行单方向通信.但是有没有办法让服务器端和客户端进行双向通信呢? 解决思 ...
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- Messenger
Messenger类实际是对Aidl方式的一层封装.本文只是对如何在Service中使用Messenger类实现与客户端的通信进行讲解,对Messenger的底层不做说明.阅读Android Prog ...
- Android系列之网络(二)----HTTP请求头与响应头
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- Android系列之Fragment(二)----Fragment的生命周期和返回栈
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- Android之自定义生成彩色二维码
先导个zxing.jar包 下面是xml布局 activity_main.xml <RelativeLayout xmlns:android="http://schemas.andro ...
- Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable
版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable 这里讲一下如何实现PS调色板中的透明度 ...
随机推荐
- 清除页面广告?身为前端,自己做一款简易的chrome扩展吧
大家肯定有这样的经历,浏览网页的时候,左右两端广告,诸如“屠龙宝刀,点击就送”,以及最近火的不行的林子聪37传奇霸业什么“霸业面具,霸业吊坠”的魔性广告总是充斥我们的眼球. 当然有现成的扩展程序或者插 ...
- 优化javaScript代码,提高执行效率
今天看完书,总结了一下可以如何优化 JavaScript . 1.合并js文件 为优化性能,可以把多个js文件(css文件也可以)合并成极少数大文件.跟十个5k的js文件相比,合并成一个50k的文件更 ...
- CentOS 7下MySQL服务启动失败的解决思路
今天,启动MySQL服务器失败,如下所示: [root@spark01 ~]# /etc/init.d/mysqld start Starting mysqld (via systemctl): Jo ...
- mysql default unix_timestamp(now())
按照mssql的创建方式,去创建mysql的默认值时间戳是不能被允许的,例如下面代码: CREATE TABLE USERINFO( CREATETIME INT NOT NULL DEFAULT U ...
- Apache Sqoop - Overview——Sqoop 概述
Apache Sqoop - Overview Apache Sqoop 概述 使用Hadoop来分析和处理数据需要将数据加载到集群中并且将它和企业生产数据库中的其他数据进行结合处理.从生产系统加载大 ...
- andriod 手机按键检测事件 onKeyDown() 简述
函数原型: public boolean onKeyDown(int keyCode, KeyEvent event); 第一个参数是用户按下键时,当前所接收到的按键代号: 第二个参数是按键事件的对象 ...
- C#中DataTable转化为List<T>解析
在.net项目中使用到DataTable和List<T>集合的地方较多, 泛型的好处: 它为使用c#语言编写面向对象程序增加了极大的效力和灵活性.不会强行对值类型进行装箱和拆箱,或对引用类 ...
- jquery.mobile手机网页简要
先上最终效果: 最近做了一个用手机浏览器访问的web应用,采用较流行的HTML5,为了提高开发效率节省时间决定采用现有开源框架,免去了自己做设计与兼容性. 一些比较优秀的框架:10大优秀的移动Web应 ...
- 轻松理解AOP思想(面向切面编程)
本文旨在帮助还没有理解AOP的童鞋看透弄懂AOP,也欢迎高手批评指正. 先说一个Spring是什么吧,大家都是它是一个框架,但框架这个词对新手有点抽象,以致于越解释越模糊,不过它确实是个框架的,但那是 ...
- DataTable数据批量写入数据库三种方法比较
DataTable数据批量写入数据库三种方法比较 标签: it 分类: C#1) insert循环插入:2) sqldataadapter.update(dataset,tablename); ...