如何写一个正经的Android音乐播放器 二

这一篇讲如何

与音乐播放Service交互

稍有经验的同学都知道,将长时间的操作放在Service中进行,如何做到界面和音乐播放Service的有效沟通呢,在这一章中给出我的答案,同样希望大神们给出指点。

希望你阅读(自行翻墙):

Service的API Guide:http://developer.android.com/guide/components/services.html

Service的API Guide中的有关bound service中的部分:

http://developer.android.com/guide/components/bound-services.html

Service的API:http://developer.android.com/reference/android/app/Service.html

首先实现一个Service类,我们命名之为MainService,那么我们应该如何启动这个Service呢?启动Service一个Service有两种方法:一种是startService (Intent);另外一种是:bindService (Intent);

第一种启动方式,适用于Service独立完成任务,例如说一个下载,如果不需要暂停或者取消的话,可以这样来做。但是,我们这是音乐播放应用,把MediaPlayer放在Service中执行播放,这样的方式很难有暂停等交互。(其实也可以这样做,例如每次交互操作都用startService来做,通过Intent把暂停等命令出入进去,进度条也可以通过广播来发送出去,但是这样做,感觉很丑陋,肯定不是常规的高效做法);

第二种启动方式,可以在onServiceConnected中,获得一个Service对象(可能不是一个Service对象,至少是一个可以接触Service内部操作的句柄)。这样,便可以轻松操作播放和接收进度通知。但是这种方式有弊端,一旦与之绑定的context退出,则绑定接触,Service也会被回收(但是不会执行onDestory方法);

那么是不是就只是简单用第二种启动方式?

当然不是这样,在谷歌官方文档中,有交代,这两种方式并不冲突,而且十分适用于音乐播放类的应用。

原文如下:

A bound service

The service is created when another component (a client) calls bindService(). The client then communicates with the service through an IBinder interface. The client can close the connection by
calling unbindService(). Multiple clients can bind to the same service and when all of them unbind, the system destroys the service. (The service does not need to stop itself.)

These two paths are not entirely separate. That is, you can bind to a service that was already started withstartService(). For example, a background music service could be started by calling startService() with
anIntent that identifies the music to play. Later, possibly when the user wants to exercise some control over the player or get information about the current song, an activity can bind to the service by calling bindService(). In cases like this, stopService() or stopSelf() does
not actually stop the service until all clients unbind.

简单理解是:可以有多个client去绑定同一个Service,并且只有所有绑定的client都解除绑定以后,Service就会被destory掉,不需要执行stopSelf方法,同样不会回调到onDestory方法;一个Client可以绑定一个已经start的Service,这样绑定的话,要停止这个service,则必须先解除一切绑定的client,然后再调用stopService或者stopSelf方法。

得到官方的说法后,就可以放心大胆的写代码了。

为了方便,我们定义一个自己的Application类——BeApplication,来执行相关操作。

public class BeApplication extends Application implements ServiceConnection {

@Override

public void onCreate() {

super.onCreate();

startMainService();

bindMainService();

}

public void startMainService () {

Intent it = new Intent (this, MainService.class);

startService(it);

}

public void stopMainService () {

Intent it = new Intent(this, MainService.class);

stopService(it);

}

private void bindMainService () {

Intent it = new Intent (this, MainService.class);

this.bindService(it, this, Service.BIND_AUTO_CREATE);

}

private void unbindMainService () {

this.unbindService(this);

}

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

if (service instanceof MainService.ServiceBinder) {

MainService.ServiceBinder binder = (MainService.ServiceBinder)service;

mMainService = binder.getService();

mMainService.registerServiceCallback(mPlayManager);

}

}

@Override

public void onServiceDisconnected(ComponentName name) {

Toast.makeText(this, "onServiceDisconnected name=" + name, Toast.LENGTH_LONG).show();

}

}

在这个Application类的onCreate方法中,我们先启动一个Service,然后绑定这个Service。注意,让自己的BeApplication能够运行,要在manifest文件中的<application/>标签下,定义android:name=”包名加我们application类的类名”。

现在写我们用音乐播放的Service类——MainService,同样记得在manfest文件中声明这个Service。

public class MainService extends Service {

public static class ServiceBinder extends Binder {

private MainService mService = null;

public ServiceBinder(MainService service) {

mService = service;

}

public MainService getService () {

return mService;

}

}

@Override

public IBinder onBind(Intent intent) {

return new ServiceBinder(this);

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

return Service.START_STICKY;

//return super.onStartCommand(intent, flags, startId);

}

}

注意之前在BeApplication中的onServiceConnected方法,我们在那个方法中,取得了由MainService中的onBind方法返回的IBinder对象,并通过这个对象,我们在BeApplication中拿到这个用于播放音乐的Service,这样以来,与Service交互容易的多。

也许你会问,这样已经拿到service对象了,那有何必要去start这个service呢?

注意MainService中的onStartCommend方法,此方法返回了一个int常量,对于这个常量,官方有这样的解释:

START_STICKY

If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with
a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.

另外 还有两个常用的常量:START_NOT_STICKY 和START_REDELIVER_INTENT ,可以在此链接进行扩展阅读:http://developer.android.com/guide/components/services.html#ExtendingService

此变量的功能在于,一旦系统杀死了这个service,在重新启动这个service的时候,onStartCommand中的intent不起作用。这适用于,在onStartCommand中,并不执行工作的Service。

附service生命周期流程图:

时间: 2025-01-13 04:32:23

如何写一个正经的Android音乐播放器 二的相关文章

如何写一个正经的Android音乐播放器 一

以前写过很多次音乐播放器,但是总有一些问题出现,例如: 1,音乐长时间播放问题(即便是放在service中去播放,依然会被杀死): 2,音乐的播放进度如何掌握?(如何利用mediaplayer.getCurrentPosition()来有效的通知界面变更进度?): 3,在我以往的经验中,音乐播放完毕下一曲时候,经常出现当前音乐播放还差几秒钟的时候就下一曲了的情况. 从网上找到教程中,通常都是一个播放器的demo,简单的直接把MediaPlayer放在了一个Activity中去操作,稍有良心的教程

如何写一个正经的Android音乐播放器 三

实现音乐的播放. 为了快速实现音乐播放,我们使用MediaPlayer而不用SoundPool,据说SoundPool比MediaPlayer的自由度更大.不过,根据我的了解,soundpool并不支持音频的解码,得自己去解码,而MeidaPlayer已经内置了一些解码方案,我看到的是,音频除了ape无损格式,都能播放. 你需要阅读: MediaPlayer API: http://developer.android.com/reference/android/media/MediaPlayer

android音乐播放器开发 SweetMusicPlayer 智能负载直插式歌词

在一份书面的使用MediaPlayer播放音乐, http://blog.csdn.net/huweigoodboy/article/details/39862773.假设没有本地歌词怎么办?如今来将一下载入在线歌词.好了,还是用那张图. 在实现这个功能的时候,lz尝试过baidu api,歌词迷api,后来选用了歌词迷api.尽管还是资源不全.并且还有非常多错误. 特别头疼的是有时候歌词竟然不分行.解析起来简直难受. 歌词迷api歌词查询地址:http://geci.me/api/lyric/

自编Win8风格Android音乐播放器应用源码(单机版)

用闲暇的两天时间,研究编写了一个类Win8风格的android音乐播放器,实现了大部分基本功能.下面看具体描述: 基本实现功能:注意事项:Android系统版本须在2.2以上,保证手机安装有SD卡(部分图标来至qq音乐和百度音乐)界面组成:欢迎界面:淡入,随机图片 由于代码不少,所以在这里贴出来也不太现实,嗯,那就上链结吧,请各位到源码天堂网站上下载吧: http://code.662p.com/view/4733.html 主界面:4个tab标签页,4宫格: --  歌曲列表界面:从sd卡中扫

android音乐播放器源码

最近研究android音乐播放器,弄了一个,还可以,可以实现播放.暂停.拖动进度等功能. 源码地址:http://download.csdn.net/detail/a358763471/8728855

android音乐播放器开发教程

android音乐播放器开发教程 android音乐播放器开发教程,布布扣,bubuko.com

[Android]音乐播放器总结

1. MediaPlayer要播放的文件主要包括3个来源:a. 用户在应用中事先自带的resource资源例如:mp = MediaPlayer.create(this, R.raw.test);b. 存储在SD卡或其他文件路径下的媒体文件例如:mp.setDataSource("/sdcard/test.mp3");c. 网络上的媒体文件例如:mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3"

Android音乐播放器源码(歌词.均衡器.收藏.qq5.0菜单.通知)

Android音乐播放器(歌词.均衡器.收藏.qq5.0菜单.通知) 一款Android音乐播放器源码,基本功能都实现了 qq5.0菜单(歌词.均衡器.收藏.qq5.0菜单.通知) 只有向右滑动出现,菜单键和指定按钮都还没有添加. 下载地址:http://www.devstore.cn/code/info/1144.html 运行截图:     热门源码下载: 高仿京东商城 Android快速开发不可或缺的11个工具类 Android快速开发框架LoonAndroid Android应用源码比较

做一个Android音乐播放器是遇到的一些困难

最近再做一个安卓的音乐播放器,是实验室里学长派的任务,我是在eclipse上进行开发的,由于没有android的基础,所以做起来困难重重. 首先是布局上的困难 1.layout里的控件属性不熟悉 2.想做一个音乐列表做不出来知道要用Listview控件,网上也找了许多的音乐播放器的代码,但导入项目中总会出错,所以想在这里请教各位 3.除了布局有困难外,实现相关功能也有困难,由于基础不行所以我并不想也做不出网上音乐播放器那么多的功能,我只想要我的播放器有播放,暂停,上一曲,下一曲的效果就行了,这还