//继续完善音乐播放器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进行进程间通信(二)的更多相关文章

  1. android:使用Messenger进行进程间通信(一)

    Messenger简介 Messenger和AIDL是实现进程间通信(interprocess communication)的两种方式. 实际上,Messenger的实现其实是对AIDL的封装. Me ...

  2. Android 基于Message的进程间通信 Messenger完全解析

    一.概述 说到Android进程间通信,大家肯定能想到的是编写aidl文件,然后通过aapt生成的类方便的完成服务端,以及客户端代码的编写.如果你对这个过程不熟悉,可以查看Android aidl B ...

  3. 【Android】17.5 利用Messenger实现进程间通信(IPC)

    分类:C#.Android.VS2015: 创建日期:2016-03-03 一.Messager类简介 本章前面曾经说过,要在Android上执行带服务的进程间通信(IPC),既可以用Messenge ...

  4. Android - 使用messager实现进程间通信(服务器端→客户端,客户端→服务器端双向)

    之前看了一篇,然后不自己动手肯定是不行的,然后自己又写了一遍. 背景: 一般使用messenger进行进程间通信的时候,我们只能进行单方向通信.但是有没有办法让服务器端和客户端进行双向通信呢? 解决思 ...

  5. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- Messenger

    Messenger类实际是对Aidl方式的一层封装.本文只是对如何在Service中使用Messenger类实现与客户端的通信进行讲解,对Messenger的底层不做说明.阅读Android Prog ...

  6. Android系列之网络(二)----HTTP请求头与响应头

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  7. Android系列之Fragment(二)----Fragment的生命周期和返回栈

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  8. Android之自定义生成彩色二维码

    先导个zxing.jar包 下面是xml布局 activity_main.xml <RelativeLayout xmlns:android="http://schemas.andro ...

  9. Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable 这里讲一下如何实现PS调色板中的透明度 ...

随机推荐

  1. Web APi入门之Self-Host寄宿及路由原理(二)

    前言 刚开始表面上感觉Web API内容似乎没什么,也就是返回JSON数据,事实上远非我所想,不去研究不知道,其中的水还是比较深,那又如何,一步一个脚印来学习都将迎刃而解. Self-Host 我们知 ...

  2. 使用jQuery封装实用函数

    一.引言 项目开发中,前端会有一个辅助工具类的js文件,比如cookie的操作,团队成员自己封装的方法.大多数时候,我们开发人员自己都是写一个全局函数,不考虑后期维护人员也会写相同的代码,然后造成代码 ...

  3. IOS-Foundation框架结构

    这些东西,等用的时候查资料就行,用的多了,自然就记住了,大概过一下 发现一个不错的 ios 学习博客:http://www.cnblogs.com/kenshincui,非常好,推荐看看.FOunda ...

  4. Windows Server 2008 下解析二级域名的方法

    昨天去了客户那里部署网站,用的是客户那边的windows server 2008. 本文主要以总结问题点的形式来说. 问题1:本机的数据库是SQL SERVER 2008R2,客户那边的数据库是SQL ...

  5. Web.Config文件配置小记

    <system.web>  <!--             设置 compilation debug="true" 将调试符号插入            已编译 ...

  6. scikit-learn一般实例之一:保序回归(Isotonic Regression)

    对生成的数据进行保序回归的一个实例.保序回归能在训练数据上发现一个非递减逼近函数的同时最小化均方误差.这样的模型的好处是,它不用假设任何形式的目标函数,(如线性).为了比较,这里用一个线性回归作为参照 ...

  7. Redis修改数据多线程并发—Redis并发锁

    本文版权归博客园和作者本人吴双共同所有 .转载爬虫请注明地址,博客园蜗牛 http://www.cnblogs.com/tdws/p/5712835.html 蜗牛Redis系列文章目录http:// ...

  8. ul li设置横排,并除去li前的圆点

    效果预览:http://hovertree.com/texiao/css/ 如何用CSS制作横向菜单 让ul li横向排列及圆点处理 我们先建立一个无序列表,来建立菜单的结构.代码是: <ul& ...

  9. 各种JS模板引擎对比数据(高性能JavaScript模板引擎)

    最近做了JS模板引擎测试,拿各个JS模板引擎在不同浏览器上去运行同一程序,下面是模板引擎测试数据:通过测试artTemplate.juicer与doT引擎模板整体性能要有绝对优势: js模板引擎 Ja ...

  10. 使用NPOI创建Excel

    一.NPOI 函式庫: NPOI 函式庫檔案有七個,NPOI 函式庫可以在 http://npoi.codeplex.com 中下載,分別是: NPOI.DLL:NPOI 核心函式庫. NPOI.DD ...