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

关于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 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();
        }
        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();
        }
    }
}

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);
        }
    }
}

当我们单击了按钮”播放音乐并退出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有所帮助。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 20:12:34

Android通过startService播放背景音乐简单示例的相关文章

Android通过startService实现批量下载示例

关于startService的基本使用概述及其生命周期可参见博客<Android中startService的使用及Service生命周期>. 本文通过批量下载文件的简单示例,演示startService以及stopService(startId)的使用流程. 系统界面如下: 界面很简单,就一个按钮"批量下载文章",通过该Activity上的按钮启动DownloadService. DownloadService是用来进行下载CSDN上博客文章的服务,代码如下: packag

百度地图 Android SDK - 检索功能使用的简单示例

百度地图 SDK 不仅为广大开发者提供了炫酷的地图展示效果.丰富的覆盖物图层,更为广大开发者提供了多种 LBS 检索的能力.通过这些接口,开发者可以轻松的访问百度的 LBS 数据,丰富自己的移动端地图应用. 目前百度地图 SDK 为开发者提供的检索服务有: POI 检索:可以检索百度 POI 数据信息: 线路规划:利用百度的引擎帮助开发者规划线路: 在线建议检索.短链接分享.地理编码等等.... 本文将以一个很简单的 POI 城市内检索为例,像广大开发者介绍接口的使用. 第一步,选择并下载 SD

最简单的基于FFmpeg的移动端样例附件:Android 自带播放器

===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:Android HelloWorld 最简单的基于FFmpeg的移动端样例:Android 视频解码器 最简单的基于FFmpeg的移动端样例:Android 视频解码器-单个库版 最简单的基于FFmpeg的移动端样例:Android 推流器 最简单的基于FFmpeg的移动端样例:Android 视频转

Android中ProgressDialog的简单示例

网上一般对进度条的示例都是如何显示,没有在任务结束如何关闭的文章,参考其他文章经过试验之后把整套进度条显示的简单示例如下: 建立android工程等工作都略去,Google一下就可以了. 下面来介绍主要的Activity ProgressBarDemo.java Java代码   package com.lveyo.android.demo.progressbar; import android.app.Activity; import android.app.ProgressDialog; i

Android中startService的使用及Service生命周期

Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法,本文只探讨startService的使用,不涉及任何bindService方法调用的情况. 当我们通过调用了Context的startService方法后,我们便启动了Service,通过startService方法启动的Service会一直无限期地运行下去,只有在外部调用Context的stopService或Service内部调用Servic

[Android应用]音乐播放器

Service是一个不可见的进程在后台执行. Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,例如我们打开一个音乐播放器来听音乐,在听音乐的同时也想做下其它的事情,比如上网聊Q.或者上网浏览新闻之类的事情.这样的话,我们就需要用到Service服务了.下面我们以一个简单的音乐播放器的实例来说明下Service的生命周期和Service的使用. 下面是音乐播放器Demo的程

iOS开发—音频的播放的简单介绍和封装工具类

iOS开发—音频的播放的简单介绍和封装工具类 一.音效的播放简单介绍 简单来说,音频可以分为2种 (1)音效 又称“短音频”,通常在程序中的播放时长为1~2秒 在应用程序中起到点缀效果,提升整体用户体验 (2)音乐 比如游戏中的“背景音乐”,一般播放时间较长 框架:播放音频需要用到AVFoundation.framework框架 二.音效的播放 1.获得音效文件的路径 NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_03.wav&qu

如何在Android实现桌面清理内存简单Widget小控件

如何在Android实现桌面清理内存简单Widget小控件 我们经常会看到类似于360.金山手机卫士一类的软件会带一个widget小控件,显示在桌面上,上面会显示现有内存大小,然后会带一个按键功能来一键清理内存,杀死后台进程的功能,那么这个功能是如何实现的呢,我们今天也来尝试做一个类似的功能的小控件. 效果图: 一.UI部分的编写: 参照Google的文档,首先在建立一个类继承AppWidgetProvider import android.appwidget.AppWidgetProvider

android之MP3播放器

布局文件 布局文件中设置了三个按钮分别来进行播放.暂停和继续播放 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="mat