概述:

其实一开始我也不没有认真想过当我们在我们的Android程序中添加背景音乐时,这项功能应该怎么实现。只是傻乎乎地在Activity中添加这项功能,并且并不认为自己这样写会有什么问题。

思路分析:

可是,我们是否想过这样一个问题:如果我们添加的音乐播放器的这个Activity异常关闭或是我们人为关闭时,我们的音乐播放还是否能够继续呢?

答案肯定是不能的。我们的Activity都关闭了,那基于这个Activity的功能又怎么可能还能继续呢?那你可能会问:那我们应该怎么去实现这个功能呢?有人可能会想到,那我就去重新new一个线程,不就好了吗?我只能说这个想法很好,不过这个是行不通的。原因可能是你现在new的这个线程是作为UI线程一个子线程,当父线程都停止工作了,子线程又怎么还会苟活!

其实,我们不要忘了,Android的四大组件中,有一个Service。它的功能类似于Activity,只是Service是在后台工作,不出现在用户的视野中。当我们在前台上进行一个人机交互操作,让这个操作关联到Service上,这样,我们就能够解决之前我们遇到的那个问题了。

Service中也有一个onCreate()的回调方法,当我们的Service被创建时就会回调这个方法。我们可以在Service被创建时,启动背景音乐。Service中也有一个onDestroy()的回调方法,当我们的Service被关闭之前会回调这个方法。这样,我们就可以在onDestroy()这个方法里,写关闭背景音乐的代码。下面我给出这个程序的前台和后台的关键代码。

前台程序:

public class MusicActivity extends Activity
{Button open, close, getTime;// 保持所启动的Service的IBinder对象MusicService.MyBinder binder;// 定义一个ServiceConnection对象private ServiceConnection conn = new ServiceConnection(){// 当该Activity与Service连接成功时回调该方法@Overridepublic void onServiceConnected(ComponentName name, IBinder service){System.out.println("--Service Connected--");// 获取Service的onBind方法所返回的MyBinder对象binder = (MusicService.MyBinder) service;}// 当该Activity与Service断开连接时回调该方法@Overridepublic void onServiceDisconnected(ComponentName name){System.out.println("--Service Disconnected--");}};@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 获取程序界面中的start、stop、<span style="font-family: Arial, Helvetica, sans-serif;">getTime</span><span style="font-family: Arial, Helvetica, sans-serif;">按钮</span>open = (Button) findViewById(R.id.bind);close = (Button) findViewById(R.id.unbind);getTime = (Button) findViewById(R.id.getServiceStatus);// 创建启动Service的Intentfinal Intent intent = new Intent();// 为Intent设置Action属性intent.setAction("com.music.service.BIND_SERVICE");open.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View source){// 绑定指定SerivcebindService(intent, conn, Service.BIND_AUTO_CREATE);}});close.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View source){// 解除绑定SerivceunbindService(conn);}});getTime.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View source){// 获取、并显示Service的count值Toast.makeText(MusicActivity.this,"Serivce的count值为:" + binder.getCount(),Toast.LENGTH_SHORT).show(); //②}});}
}

后台程序:

public class MusicService extends Service
{private int count;private boolean close;MediaPlayer m_PlayMid = null;// 定义onBinder方法所返回的对象private MyBinder binder = new MyBinder();// 通过继承Binder来实现IBinder类public class MyBinder extends Binder //①{public int getCount(){// 获取Service的运行状态:countreturn count;}}// 必须实现的方法,绑定该Service时回调该方法@Overridepublic IBinder onBind(Intent intent){System.out.println("Service is Binded");// 返回IBinder对象return binder;}// Service被创建时回调该方法。@Overridepublic void onCreate(){super.onCreate();System.out.println("Service is Created");m_PlayMid = MediaPlayer.create(this, R.raw.just_the_way_you_are);m_PlayMid.setLooping(true);// 启动一条线程、动态地修改count状态值new Thread(){@Overridepublic void run(){while (!close){try{Thread.sleep(1000);}catch (InterruptedException e){}count++;m_PlayMid.start();}}}.start();}// Service被断开连接时回调该方法@Overridepublic boolean onUnbind(Intent intent){System.out.println("Service is Unbinded");return true;}// Service被关闭之前回调该方法。@Overridepublic void onDestroy(){super.onDestroy();this.close = true;m_PlayMid.stop();System.out.println("Service is Destroyed");}
}


源代码分享:

下面是我的Demo源码地址:用Service来启动背景音乐

如何用Service来启动背景音乐相关推荐

  1. 如何用命令行启动mysql_命令行方式启动mysql 如何用命令行启动mysql

    如何用命令行启动mysql,有时候,仅是简单的想在电脑上启动myql,当然如果用myql图形管理器也是可以的,比如avicate以及qlyog,本经验教你如何使用命令行启动myql. 如何用命令行进入 ...

  2. windows8.1 windows defender service无法启动解决方案

    windows8.1 windows defender service无法启动解决方案 参考文章: (1)windows8.1 windows defender service无法启动解决方案 (2) ...

  3. 在Openstack上部署compute节点上时,开启服务openstack-nova-compute.service无法启动的解决方法

    在Openstack上部署compute节点上时,开启服务openstack-nova-compute.service无法启动的解决方法 参考文章: (1)在Openstack上部署compute节点 ...

  4. android服务的启动过程,Android Service的启动过程(上)

    原标题:Android Service的启动过程(上) (点击上方公众号,可快速关注) 来源:伯乐在线专栏作者 - xuyinhuan 链接:http://android.jobbole.com/85 ...

  5. Android中Service的启动方式及Activity与Service的通信方式

    Service启动的两种方式 1.通过startService启动 使用Service的步骤: 定义一个类继承Service 在Manifest.xml文件中配置该Service 使用Context的 ...

  6. VMware虚拟机VMware Authorization Service不能启动问题

    出现VMware Authorization Service不能启动问题,注意要在安装VMware Player时使用管理员权限 转载于:https://www.cnblogs.com/mingzha ...

  7. Android WifiDisplay分析一:相关Service的启动

    网址:http://www.2cto.com/kf/201404/290996.html 最近在学习Android 4.4上面的WifiDisplay(Miracast)相关的模块,这里先从WifiD ...

  8. Android Service的启动过程

    刚开始学习Service的时候以为它是一个线程的封装,也可以执行耗时操作.其实不然,Service是运行在主线程的.直接执行耗时操作是会阻塞主线程的.长时间就直接ANR了. 我们知道Service可以 ...

  9. VMware DHCP Service服务启动时报错:错误1068 依存服务或组无法启动

    VMware DHCP Service服务启动时报错:错误1068 依存服务或组无法启动 解决办法: 1.选择虚拟网络编辑器 ok了,问题解决 来自为知笔记(Wiz) 转载于:https://www. ...

最新文章

  1. 成功解决ValueError: Shape of passed values is (33, 1), indices imply (33, 2)
  2. Linux上DNS实现工具之bind详叙
  3. 【机器视觉】——相机和镜头的选择
  4. SaltStack的salt-ssh使用及LAMP状态设计部署
  5. CLR via C# 之管中窥豹(一)
  6. Centos7下配置安装mysql5.5主从复制(一主两从)
  7. core Animation动画
  8. echarts grid的样式位置_CSS Grid 系列(下)-使用Grid布局构建网站首页
  9. kylin cube 增量和全量
  10. Treap 树堆 容易实现的平衡树
  11. 再谈KMP/BM算法(II)
  12. 为什么html中图片显示不出来,网页图片不显示怎么回事?网页图片不显示的解决方法...
  13. 童心未泯?LEGO积木iPod touch外壳,自己拼积木!
  14. 京东云服务器搭建php开发环境
  15. 微信小程序操作es简单搜索
  16. PCIe driver
  17. Linux源码编译安装步骤及命令
  18. IOST 项目更新:BB ,展望正面 | TokenInsight
  19. ps42k20服务器出现问题_香港代理服务器和香港服务器有什么不同,如何选择?-行业新闻...
  20. 解决“不能读取 AppletViewer 的属性文件”的问题

热门文章

  1. 近世代数--子环--怎么判断是不是子环?
  2. 创新实训个人记录 : 个人工作总结
  3. 操作系统实验——简易FAT16文件系统的实现
  4. 密码技术应用--RSA文件签名验签
  5. 【Flask项目2】定制统一的JSON返回格式(6)
  6. python通过requirements.txt文件批量安装依赖包的实现步骤
  7. [CISCN2018]crackme-java
  8. (37)0环与3环通信常规方式,PspTerminateProcess 关闭进程工具
  9. Apache Log4j2 RCE 命令执行漏洞预警及修复方案
  10. 005 定位控件输入call