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

2024-02-19 19:18

本文主要是介绍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 android.widget.Toast;import java.io.IOException;public class MusicService extends Service {private MediaPlayer mediaPlayer = null;private boolean isReady = false;@Overridepublic void onCreate() {//onCreate在Service的生命周期中只会调用一次super.onCreate();//初始化媒体播放器mediaPlayer = MediaPlayer.create(this, R.raw.music);if(mediaPlayer == null){return;}mediaPlayer.stop();mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {@Overridepublic 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);}}@Overridepublic 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;}@Overridepublic IBinder onBind(Intent intent) {//该Service中不支持bindService方法,所以此处直接返回nullreturn null;}@Overridepublic 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 {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_music);}@Overridepublic void onClick(View v) {if(v.getId() == R.id.btnStart){//播放背景音乐Intent intent = new Intent(this, MusicService.class);startService(intent);//退出当前Activitythis.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有所帮助。

这篇关于Android通过startService播放背景音乐简单示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/725682

相关文章

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE

pandas中位数填充空值的实现示例

《pandas中位数填充空值的实现示例》中位数填充是一种简单而有效的方法,用于填充数据集中缺失的值,本文就来介绍一下pandas中位数填充空值的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是中位数填充?为什么选择中位数填充?示例数据结果分析完整代码总结在数据分析和机器学习过程中,处理缺失数