nbhkdz.com冰点文库

Android培训之通过startService播放背景音乐简单示例

时间:2016-01-05


北京尚学堂提供
关于 startService 的基本使用概述及其生命周期可参见博客《Android 中 startService 的使用及 Service 生命周期》。

本文通过播放背景音乐的简单示例,演示 startService 的基本使用流程。

系统界面如下:

界面上面就两个按钮,”播放音乐并退出 Activity” 和 “停止播放音乐”。我们在该示例中,通过操纵 Activity 的按钮控制 MusicService 播放或停止播放音乐。

我将一个名为 music.mp3 的放到资源目录/res/raw 文件夹下面,这样我们在程序中就可以通过 R.raw.music 引用该音乐文 件,放入/res/raw 文件夹中的资源文件会保持原来的面貌不会被编译成二进制。

MusicService 是用于播放背景音乐的 Service,其代码如下所示:

package com.ispring.startservicedemo;

import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.IBinder; import android.widget.Toast;

import java.io.IOException;

public class MusicService extends Service {

private MediaPlayer mediaPlayer = null;

private boolean isReady = false;

@Override public void onCreate() { //onCreate 在 Service 的生命周期中只会调用一次

super.onCreate();

//初始化媒体播放器 mediaPlayer = MediaPlayer.create(this, R.raw.musi c); if(mediaPlayer == null){ return; }

mediaPlayer.stop(); mediaPlayer.setOnErrorListener(new MediaPlayer.OnEr rorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { mp.release(); stopSelf(); return false; } });

try{ mediaPlayer.prepare(); isReady = true; } catch (IOException e) {

e.printStackTrace(); isReady = false; }

if(isReady){ //将背景音乐设置为循环播放 mediaPlayer.setLooping(true); } }

@Override public int onStartCommand(Intent intent, int flags, int startId) { //每次调用 Context 的 startService 都会触发 onStartComman d 回调方法

//所以 onStartCommand 在 Service 的生命周期中可能会被调用多 次 if(isReady && !mediaPlayer.isPlaying()){ //播放背景音乐 mediaPlayer.start(); Toast.makeText(this, "开始播放背景音乐", Toast.LEN GTH_LONG).show(); }

return START_STICKY; }

@Override public IBinder onBind(Intent intent) { //该 Service 中不支持 bindService 方法,所以此处直接返回 nu ll return null; }

@Override public void onDestroy() { //当调用 Context 的 stopService 或 Service 内部执行 stopSe lf 方法时就会触发 onDestroy 回调方法 super.onDestroy(); if(mediaPlayer != null){ if(mediaPlayer.isPlaying()){ //停止播放音乐 mediaPlayer.stop(); } //释放媒体播放器资源 mediaPlayer.release();

Toast.makeText(this, "停止播放背景音乐", Toast.LEN GTH_LONG).show(); } } }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

? ? ? ? ?

80 81 82 83 84

MusicActivity 的代码如下所示:

package com.ispring.startservicedemo;

import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button;

public class MusicActivity extends Activity implements But ton.OnClickListener {

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_music); }

@Override public void onClick(View v) {

if(v.getId() == R.id.btnStart){ //播放背景音乐 Intent intent = new Intent(this, MusicService.cl ass); startService(intent); //退出当前 Activity this.finish(); }else if(v.getId() == R.id.btnStop){ //停止播放音乐 Intent intent = new Intent(this, MusicService.cl ass); stopService(intent); } } }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

当我们单击了按钮”播放音乐并退出 Activity”之后,我们首先通过 Activity 的 startService 启动 MusicService,然后我们立 即调用了 Activity 的 finish 方法销毁了当前的 Activity。可能大家会问为什么要销毁当前的 Activity?我们此处之所以调 用 Activity 的 finish 方法不是从功能的角度出发的,而是从理解代码运行的角度故意这么写的: 执行完 Activity 的 finish 方法之后,当前的 Activity 就销毁了, 在界面上看起来就是当前 UI 消失了,应用程序退出了,但稍等片刻你会听到背 景音乐响起。这从侧面印证了 Service 的一个特性: Service 与 Activity 等一样,也是一种基本的应用程序组件,Service 无需依赖任何的 Activity 便可独自在没有任何 UI 界面的情况下悠闲地在 Android 后台默默运行。

调用了 startService 之后, Android Framework 接收到了 intent 信息, 第一次会先创建 MusicService 的实例, 执行 MusicService 的 onCreate 回调方法,onCreate 在 Service 的生命周期中只会调用一次,我们在其 onCreate 方法中将 R.raw.music 初始化 为媒体播放器,并调用媒体播放器的 prepare 方法。然后我们将播放器设置为循环播放状态。需要注意的是,在实际生 产环境中,我们应该注册播放器的 setOnPreparedListener 并调用 prepareAsync()方法,为了简化代码起见,我们只调用了 播放器的同步方法 prepare()。

调用了 onCreate 方法后,Android 会自动回调其 onStartCommand 方法,其实每次调用 Context 的 startService 都会触发 onStartCommand 回调方法,所以 onStartCommand 在 Service 的生命周期中可能会被调用多次。所以我们在 MusicService 的 onStartCommand 中做了判断,判断播放器是否是在播放中,如果当前播放器没有播放我们才调用播放器的 start 方法 播放背景音乐。

当我们单击了按钮”播放音乐并退出 Activity”之后,MusicService 启动起来,播放背景音乐,但是 Activity 却销毁了,程 序的 UI 界面不见了。为了能够停止播放背景音乐,我们需要再次单击应用程序图标,重新打开 MusicActivity,然后单

击界面上的”停止播放音乐”按钮,此时我们会调用 Activity 的 stopService 方法,Android Framework 接收到要停止服务的 intent 之后会回调 MusicService 的 onDestroy 方法,在该方法中我们停止播放音乐并释放媒体播放器资源。

本文只是通过播放背景音乐这一简单示例演示通过 startService 启动 Service 基本使用流程,代码没有进行优化,希望对 大家学习 Service 有所帮助。

出版:北京尚学堂 网址:www.bjsxt.com QQ 群:516745661


赞助商链接

android——Service

四、 Service 示例 下面我做了一个简单音乐播放的应用, 分别使用 start...通过 startService(intent); 服务后发送出去 Bundle bundle = new Bundle(); ...

Android小项目之“音乐播放器”

Android小项目之“音乐播放器”_计算机软件及应用_IT...service、BroadcastReceiver 等基础知识,就它们来做...(fd.getFileDescriptor,fd.getStartOffset(),fd ....

android service 学习

下面我做了一个简单音乐播放的应用,分别使用 startService 和 bindService 来启动本地的服务. 而在下一篇《android service 学习(下) 》会介绍通过 AIDL 对 ...

Android应用开发入门实战关于Service

Android应用开发入门实战关于Service_计算机软件及应用_...音乐依然可 以继续播放,这时就是由服务 (service)...用于应用程序内部,通过调用 Context.startService()...

android service 相关知识

下面我做了一个简单音乐播放的应用,分别使用 startService 和 bindService 来启动本地的服务。 而在下一篇《android service 学习(下) 》会介绍通过 AIDL 对 ...

android_service

比如,服务可以处理网络传输、音乐播放、执行文 件I/...举个例子,假定某activity需要把一些数据保存到在线...startId); } } AndroidManifest.xml <service android...

Android Service介绍

Android Service介绍_计算机软件及应用_IT/计算机_专业...例如:文件下载、背景音乐播放。。。 Service:主要...生命周期 通过 startService 启动服务,若服务未启动,...

基于Android的在线音乐播放器开发

android 中使用 JSOUP 如何解析网页数据详述 网络歌曲...startService()方法启动过该音乐播放服务了 * 那么...// 获取 MusicIconLoader 的实例 public synchronized...

Android之Service的细枝末节

Android 之 Service 的细枝末节进程 Service 是一种...onStartCommand(),其他组件通过 startService()启动...状态栏通 知显示正在播放歌曲,并允许其他组件与其...

Android基础之四大根本组件介绍与生命周期

比较好的一个例子就是一个正在从播放列表中播放歌曲的媒体播放器。在一个媒体 ...service name=".SMSService"/> 服务不能自己运行,需要通过 Contex.startService...