关于startservice的基本使用概述及其生命周期可参见《android中startservice基本使用方法概述》。
本文通过播放背景音乐的简单示例,演示startservice的基本使用流程,具体内容如下
系统界面如下:
界面上面就两个按钮,”播放音乐并退出activity” 和 “停止播放音乐”。我们在该示例中,通过操纵activity的按钮控制musicservice播放或停止播放音乐。
我将一个名为music.mp3的放到资源目录/res/raw文件夹下面,这样我们在程序中就可以通过r.raw.music引用该音乐文件,放入/res/raw文件夹中的资源文件会保持原来的面貌不会被编译成二进制。
musicservice是用于播放背景音乐的service,其代码如下所示:
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
|
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.music);
if (mediaplayer == null ){
return ;
}
mediaplayer.stop();
mediaplayer.setonerrorlistener( new mediaplayer.onerrorlistener() {
@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都会触发onstartcommand回调方法
//所以onstartcommand在service的生命周期中可能会被调用多次
if (isready && !mediaplayer.isplaying()){
//播放背景音乐
mediaplayer.start();
toast.maketext( this , "开始播放背景音乐" , toast.length_long).show();
}
return start_sticky;
}
@override
public ibinder onbind(intent intent) {
//该service中不支持bindservice方法,所以此处直接返回null
return null ;
}
@override
public void ondestroy() {
//当调用context的stopservice或service内部执行stopself方法时就会触发ondestroy回调方法
super .ondestroy();
if (mediaplayer != null ){
if (mediaplayer.isplaying()){
//停止播放音乐
mediaplayer.stop();
}
//释放媒体播放器资源
mediaplayer.release();
toast.maketext( this , "停止播放背景音乐" , toast.length_long).show();
}
}
}
|
musicactivity的代码如下所示:
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
|
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 button.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. class );
startservice(intent);
//退出当前activity
this .finish();
} else if (v.getid() == r.id.btnstop){
//停止播放音乐
intent intent = new intent( this , musicservice. class );
stopservice(intent);
}
}
}
|
当我们单击了按钮”播放音乐并退出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有所帮助。