Android通过startService播放背景音乐简单演示样例
关于startService的基本使用概述及其生命周期可參见博客《Android中startService的使用及Service生命周期》。
本文通过播放背景音乐的简单演示样例,演示startService的基本使用流程。
系统界面例如以下:
界面上面就两个button。”播放音乐并退出Activity” 和 “停止播放音乐”。
我们在该演示样例中。通过操纵Activity的button控制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.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的代码例如以下所看到的:
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);
}
}
}
当我们单击了button”播放音乐并退出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方法播放背景音乐。
当我们单击了button”播放音乐并退出Activity”之后,MusicService启动起来,播放背景音乐,可是Activity却销毁了,程序的UI界面不见了。
为了可以停止播放背景音乐,我们须要再次单击应用程序图标,又一次打开MusicActivity。然后单击界面上的”停止播放音乐”button,此时我们会调用Activity的stopService方法,Android Framework接收到要停止服务的intent之后会回调MusicService的onDestroy方法,在该方法中我们停止播放音乐并释放媒体播放器资源。
本文仅仅是通过播放背景音乐这一简单演示样例演示通过startService启动Service基本使用流程。代码没有进行优化。希望对大家学习Service有所帮助。
Android通过startService播放背景音乐简单演示样例的更多相关文章
- Introspector(内省)简单演示样例 与 简单应用
简单演示样例: package com.asdfLeftHand.test; import java.beans.BeanDescriptor; import java.beans.BeanInfo; ...
- JBoss 系列九十六:JBoss MSC - 简介及一个简单演示样例
什么是 JBoss MSC JBoss MSC 即 JBoss Modular Service Container,是第三代 JBoss 产品 JBoss 7和WildFfly的内核,JBoss MS ...
- Thrift的安装和简单演示样例
本文仅仅是简单的解说Thrift开源框架的安装和简单使用演示样例.对于具体的解说,后面在进行阐述. Thrift简述 ...
- [hadoop系列]Pig的安装和简单演示样例
inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ).(来源:http://blog.csdn.net/inkfish) Pig是Yaho ...
- 一则简单演示样例看Oracle的“无私”健壮性
Oracle的强大之处就在于他能总帮助让你选择正确的运行计划,即使你给了它错误的指示. 实验: 1. 创建測试表: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...
- 百度地图 Android SDK - 检索功能使用的简单演示样例
百度地图 SDK 不仅为广大开发人员提供了炫酷的地图展示效果.丰富的覆盖物图层,更为广大开发人员提供了多种 LBS 检索的能力. 通过这些接口,开发人员能够轻松的訪问百度的 LBS 数据,丰富自己的移 ...
- [Android]RecyclerView的简单演示样例
去年google的IO上就展示了一个新的ListView.它就是RecyclerView. 下面是官方的说明,我英语能力有限,只是我大概这么理解:RecyclerView会比ListView更具有拓展 ...
- 虚幻4Matinee功能 基本概念及简单演示样例(Sequence编辑器)
虚幻4提供的Matinee功能十分强大,能够用来制作动画.录制视频. 它的核心想法是在Matinee编辑器内提供一套自己的时间坐标系,在这个相对时间内通过调节actor的属性来改变actor的状态,进 ...
- MyBatis对数据库的增删改查操作,简单演示样例
之前一直有用Hibernate进行开发.近期公司在使用Mybatis.依据网上的演示样例,做了一个简单的Demo,以便日后复习 使用XMl方式映射sql语句 整体结构例如以下图 watermark/2 ...
随机推荐
- ajax的几个面试题
一.什么是AJAX(请谈一下你对Ajax的认识)AJAX是“Asynchronous JavaScript and XML”的缩写.他是指一种创建交互式网页应用的网页开发技术.Ajax包含下列技术:基 ...
- CCF模拟题 最优灌溉
最优灌溉 时间限制: 1.0s 内存限制: 256.0MB 问题描述 雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉. 为了灌溉,雷雷需 ...
- 洛谷—— P2580 于是他错误的点名开始了
https://www.luogu.org/problem/show?pid=2580 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 他会一边搓炉石一边点名以至于有一天他连续点到了某个同学两次 ...
- 游戏开发之UDK引擎介绍和模型导入
2014-09-18 10:01:3 3.7.5" style="border:0px; vertical-align:middle; max-width:100%"&g ...
- 九度 题目1154:Jungle Roads
题目描写叙述: The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid mon ...
- POJ 2138 最长路
思路: 如果j能由i得到 则i向j连一条边 答案就是最长路的末节点所代表的string //By SiriusRen #include <cstdio> #include <cstr ...
- 用Nagios监控Sql Server服务器
在Suse 下配置Nagios来监控Ms SQL Server操作演示 本文出自 "李晨光原创技术博客" 博客,谢绝转载!
- c# 装箱与拆箱的概念
1装箱 就是将值类型的数据赋值给引用类型的实例中 比如 int类型的123赋值给Object o int i=123; Object o=(Object) i; 2拆箱 就是从引用类型的数据中提取数据 ...
- 请求头header里的contentType为application/json和capplition/x-www-form-urlencoded
application/x-www-form-urlencoded 最常见的 POST 提交数据的方式了.浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 ...
- python自学群里遇到的小题汇总
题目一: 请使在3秒内计算出一组的数据,偶数在奇数前(注意不使用for while等循环的方法)格式如下1,2,3,4,5,6,7,8,9,10输出结果是2,1,4,3,6,5,8,7,10,9 解决 ...