在
Android应用程序里,有一种没有UI的类(
Android.app.Service)——Service。简单来说,Service是一个 background process(背景程序),通过背景程序,可以实现一些不需要UI的功能,比如播放背景音乐。
下面是一个实现播放背景音乐的例程:
在上个工程的基础上,在Activity中添加音乐播放功能。
在工程中添加一个新类yypService(File->New->Class):
[
java] </pre><pre name="code" class="
java">import
Android.app.Service;
import
Android.content.Intent;
import
Android.os.IBinder;
public class yypService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
</pre><pre name="code" class="
java">import
Android.app.Service;
import
Android.content.Intent;
import
Android.os.IBinder;
public class yypService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
yypService 类继承
Android.app.Service,几个有关Service 的重要概念如下:
1. Service 对象以 separated process 的方式执行,这表示 Service 与 UI(Activity)并不在同一个 process 里执行,而是各自在不同的 process 执行。
2.
Android应用程序是在 Activity 启动与停止 Service。
3. 重载(override)onStart() 方法(method)在 Service 被启动,执行我们想要的背景功能。
4. 重载 onDestroy() 方法在 Service 被停止时,停止执行中的背景功能。
下面是Service的具体实现:
[
java] package com.
Android;
import
java.io.IOException;
import
Android.app.Service;
import
Android.content.Intent;
import
Android.media.MediaPlayer;
import
Android.os.IBinder;
public class yypService extends Service {
private MediaPlayer mp;
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
// 开始播放音乐
mp.start();
// 音乐播放完毕的事件处理
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
// 循环播放
try {
mp.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
// 播放音乐时发生错误的事件处理
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
// 释放资源
try {
mp.release();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
});
super.onStart(intent, startId);
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
// 初始化音乐资源
try {
// 创建MediaPlayer对象
mp = new MediaPlayer();
// 将音乐保存在res/raw/xingshu.mp3,R.
java中自动生成{public static final int xingshu=0x7f040000;}
mp = MediaPlayer.create(yypService.this, R.raw.xingshu);
// 在MediaPlayer取得播放资源与stop()之后要准备PlayBack的状态前一定要使用MediaPlayer.prepeare()
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
// 服务停止时停止播放音乐并释放资源
mp.stop();
mp.release();
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
package com.
Android;
import
java.io.IOException;
import
Android.app.Service;
import
Android.content.Intent;
import
Android.media.MediaPlayer;
import
Android.os.IBinder;
public class yypService extends Service {
private MediaPlayer mp;
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
// 开始播放音乐
mp.start();
// 音乐播放完毕的事件处理
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
// 循环播放
try {
mp.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
// 播放音乐时发生错误的事件处理
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
// 释放资源
try {
mp.release();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
});
super.onStart(intent, startId);
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
// 初始化音乐资源
try {
// 创建MediaPlayer对象
mp = new MediaPlayer();
// 将音乐保存在res/raw/xingshu.mp3,R.
java中自动生成{public static final int xingshu=0x7f040000;}
mp = MediaPlayer.create(yypService.this, R.raw.xingshu);
// 在MediaPlayer取得播放资源与stop()之后要准备PlayBack的状态前一定要使用MediaPlayer.prepeare()
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
// 服务停止时停止播放音乐并释放资源
mp.stop();
mp.release();
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
至此,一个完整的服务生成,接下来是在Activity中启动服务。
修改
AndroidManifest.xml
在 Package Explorer 视窗里找到目前
Android 项目的资讯描述档,名称为
AndroidManifest.xml。这是一个用來描述
Android 应用程序「整体资讯」的文件,每个
Android 应用程序项目都会有一个。在这里修改
Androidmanifest.xml 的目的是为了「
Android 应用程序加入一个 Service 类别」,这样才有办法驱动 Service。
[html] <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:
Android="http://schemas.
Android.com/apk/res/
Android"
package="com.
Android"
Android:versionCode="1"
Android:versionName="1.0" >
<uses-sdk
Android:minSdkVersion="10" />
<application
Android:icon="@drawable/ic_launcher"
Android:label="@string/app_name" >
<activity
Android:name=".
webTestActivity"
Android:label="@string/app_name" >
<intent-filter>
<action
Android:name="
Android.intent.action.MAIN" />
<category
Android:name="
Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
Android:name=".yypService"
Android:exported="true"
Android:process=":remote">
</service>
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:
Android="http://schemas.
Android.com/apk/res/
Android"
package="com.
Android"
Android:versionCode="1"
Android:versionName="1.0" >
<uses-sdk
Android:minSdkVersion="10" />
<application
Android:icon="@drawable/ic_launcher"
Android:label="@string/app_name" >
<activity
Android:name=".WebTestActivity"
Android:label="@string/app_name" >
<intent-filter>
<action
Android:name="
Android.intent.action.MAIN" />
<category
Android:name="
Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
Android:name=".yypService"
Android:exported="true"
Android:process=":remote">
</service>
</application>
</manifest>
配置好之后,接下来就是在Activity中添加启动服务代码 Service - startService()。
在OnCreate()中添加如下代码:
[
java] Intent intent = new Intent(WebTestActivity.this,yypService.class);
startService(intent);
Intent intent = new Intent(WebTestActivity.this,yypService.class);
startService(intent);
Activity 类里有一个 method 叫做 startService:
startService(Intent service)
调用 startService() 即可启动一个 Service ,只是,startService() 的参数是一个「Intent」型,并不是所要启动的类名。「Intent」是一个很像「Event」的类,暂时还没对Intent做深入研究,就先把它当作一个"Event"看吧?
现在,其实已经可以在Activity中播放背景音乐了,但有一个小问题,就是Activity已经被挂起或是被销毁时,背景音乐还是在继续播放的,这也说明Service与Activity是两个不同的进程,我们收下尾,让Activity在OnStop时把背景音乐也停止播放,重载Activity的OnStop:
[
java] @Override
protected void onStop() {
// TODO Auto-generated method stub
Intent intent = new Intent(WebTestActivity.this,yypService.class);
stopService(intent);
super.onStop();
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
Intent intent = new Intent(WebTestActivity.this,yypService.class);
stopService(intent);
super.onStop();
}
备注:eclipse的使用小技巧,快速补全重载代码(快捷键Alt+Shift+s -> Override/implement Mothods)。
至此,一个完整的播放背景音乐功能已经全部完成。