沧浪勇者 發表於 2025-11-18 08:45:30

使用Android Service实现后台音乐播放功能

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>前言</li><li>前置准备</li><li>一、Service核心概念</li><ul class="second_class_ul"><li>1.1 什么是Service?</li><li>1.2 Service生命周期(重点)</li><li>1.3 项目结构总览</li></ul><li>二、代码实现</li><ul class="second_class_ul"><li>2.1 第一步:添加音乐资源</li><li>2.2 第二步:编写Service核心类(MusicService.java)</li><li>2.3 第三步:编写界面布局(activity_service.xml)</li><li>2.4 第四步:编写Activity交互逻辑(ServiceActivity.java)</li><li>2.5 第五步:注册组件(AndroidManifest.xml)</li></ul><li>三、运行测试</li><ul class="second_class_ul"></ul></ul></div><p class="maodian"></p><h2>前言</h2>
<p>本文将聚焦Android另一个核心组件&mdash;&mdash;<strong>Service(服务)</strong>,它是运行在后台的&ldquo;无界面组件&rdquo;,适合执行长时间运行的任务(如音乐播放、文件下载、网络请求)。</p>
<p>本文将基于 <code>Android Studio 2025.1.4 + 模拟器Android 14</code> 环境,手把手实现&ldquo;后台音乐播放&rdquo;功能:通过Service管理音乐播放/暂停逻辑,Activity作为界面交互入口,让你彻底理解Service的生命周期、启动/停止方式以及组件间的通信逻辑。</p>
<p class="maodian"></p><h2>前置准备</h2>
<p>开始前确保以下环境和资源就绪:</p>
<ul><li><strong>开发工具</strong>:Android Studio 2025.1.4</li><li><strong>模拟器/真机</strong>:Android 14(API 34)</li><li><strong>音乐资源</strong>:准备一首MP3格式音乐,命名为<code>music.mp3</code>(后续放入<code>res/raw</code>文件夹)</li><li><strong>核心知识点</strong>:了解Android组件基础、Intent通信(前序博客已覆盖)</li></ul>
<p class="maodian"></p><h2>一、Service核心概念</h2>
<p class="maodian"></p><h3>1.1 什么是Service?</h3>
<p>Service是Android四大组件之一,运行在<strong>主线程后台</strong>(非独立进程),无可视化界面,适合执行不需要用户交互的长时间任务。</p>
<table><thead><tr><th style="text-align:center">Service核心特性</th><th style="text-align:center">说明</th><th style="text-align:center">类比场景</th></tr></thead><tbody><tr><td style="text-align:center">无界面</td><td style="text-align:center">不占用屏幕空间,后台运行</td><td style="text-align:center">电脑后台的音乐播放器进程</td></tr><tr><td style="text-align:center">生命周期长</td><td style="text-align:center">即使Activity销毁,Service可继续运行</td><td style="text-align:center">关闭视频软件窗口,背景音乐仍播放</td></tr><tr><td style="text-align:center">主线程运行</td><td style="text-align:center">默认在主线程执行,耗时操作需手动开子线程</td><td style="text-align:center">需配合Thread/AsyncTask处理耗时任务</td></tr></tbody></table>
<p class="maodian"></p><h3>1.2 Service生命周期(重点)</h3>
<p>本次实战使用&ldquo;启动式Service&rdquo;(<code>startService()</code>启动,<code>stopService()</code>停止),核心生命周期方法如下:</p>
<ol><li><code>onCreate()</code>:Service首次创建时调用(仅执行1次),用于初始化资源(如创建MediaPlayer);</li><li><code>onStartCommand()</code>:每次调用<code>startService()</code>时触发,用于执行具体业务逻辑(如播放音乐);</li><li><code>onDestroy()</code>:Service销毁时调用(执行<code>stopService()</code>或系统回收),用于释放资源(如停止播放、释放MediaPlayer)。</li></ol>
<p class="maodian"></p><h3>1.3 项目结构总览</h3>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025111808435280.png" /></p>
<div class="jb51code"><pre class="brush:plain;">com.example.ch9service
├── MusicService.java       // 核心Service:管理音乐播放/暂停/释放
├── ServiceActivity.java    // 界面Activity:提供播放/暂停按钮交互
├── res
│   ├── raw               // 音乐资源文件夹(存放music.mp3)
│   │   └── music.mp3
│   ├── layout
│   │   └── activity_service.xml// 界面布局(仅1个按钮)
│   └── values
│       └── strings.xml
└── AndroidManifest.xml   // 清单文件:注册Service和Activity
</pre></div>
<p class="maodian"></p><h2>二、代码实现</h2>
<p class="maodian"></p><h3>2.1 第一步:添加音乐资源</h3>
<ol><li>在<code>res</code>文件夹下新建<code>raw</code>文件夹(右键res&rarr;New&rarr;Android Resource Directory&rarr;Resource type选raw);</li><li>将MP3音乐文件放入<code>raw</code>文件夹,命名为<code>music.mp3</code>(注意:文件名只能包含字母、数字和下划线,不能有中文)。</li></ol>
<p class="maodian"></p><h3>2.2 第二步:编写Service核心类(MusicService.java)</h3>
<p><code>MusicService</code>负责音乐播放的核心逻辑:初始化MediaPlayer、播放、停止、释放资源,通过静态变量<code>ispaly</code>记录播放状态。</p>
<div class="jb51code"><pre class="brush:java;">package com.example.ch9service;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;

// 后台音乐播放Service
public class MusicService extends Service {
    private MediaPlayer player; // 音乐播放器实例
    public static boolean ispaly = false; // 播放状态标记(静态变量,供Activity访问)

    public MusicService() {
      // 必须实现的构造方法(无参)
    }

    @Override
    public IBinder onBind(Intent intent) {
      // 启动式Service无需绑定,返回null即可(若为绑定式Service需实现)
      throw new UnsupportedOperationException("Not yet implemented");
    }

    // Service创建时调用(仅1次):初始化MediaPlayer
    @Override
    public void onCreate() {
      super.onCreate();
      // 创建MediaPlayer实例,加载raw文件夹中的音乐资源
      player = MediaPlayer.create(this, R.raw.music);
      // 设置音乐循环播放(可选,根据需求调整)
      player.setLooping(true);
    }

    // 每次调用startService()时触发:执行播放逻辑
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
      // 若未在播放,则启动播放
      if (!player.isPlaying()) {
            player.start(); // 开始播放音乐
            ispaly = player.isPlaying(); // 更新播放状态为true
      }
      // 返回值:Service被系统回收后是否重建,START_STICKY表示重建
      return super.onStartCommand(intent, flags, startId);
    }

    // Service销毁时调用:释放资源(关键,避免内存泄漏)
    @Override
    public void onDestroy() {
      super.onDestroy();
      if (player != null) {
            player.stop(); // 停止播放
            ispaly = player.isPlaying(); // 更新播放状态为false
            player.release(); // 释放MediaPlayer资源
            player = null; // 置空,便于GC回收
      }
    }
}
</pre></div>
<p class="maodian"></p><h3>2.3 第三步:编写界面布局(activity_service.xml)</h3>
<p>布局仅包含1个按钮,用于切换&ldquo;播放&rdquo;和&ldquo;暂停&rdquo;状态,采用ConstraintLayout居中布局。</p>
<div class="jb51code"><pre class="brush:xml;">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ServiceActivity"&gt;

    &lt;!-- 播放/暂停切换按钮 --&gt;
    &lt;Button
      android:id="@+id/button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="播放音乐"
      android:textSize="18sp"
      android:paddingHorizontal="30dp"
      android:paddingVertical="10dp"
      &lt;!-- 约束布局:水平+垂直居中 --&gt;
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintEnd_toEndOf="parent" /&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;
</pre></div>
<p class="maodian"></p><h3>2.4 第四步:编写Activity交互逻辑(ServiceActivity.java)</h3>
<p><code>ServiceActivity</code>作为界面入口,通过按钮点击事件启动/停止<code>MusicService</code>,并根据<code>ispaly</code>状态切换按钮文本。</p>
<div class="jb51code"><pre class="brush:java;">package com.example.ch9service;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class ServiceActivity extends AppCompatActivity {

    private Button playBtn; // 播放/暂停按钮

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      EdgeToEdge.enable(this); // 启用沉浸式布局
      setContentView(R.layout.activity_service);

      // 适配系统状态栏(避免按钮被遮挡)
      ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -&gt; {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
      });

      // 绑定按钮控件
      playBtn = findViewById(R.id.button);
      // 设置按钮点击事件
      playBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 创建Intent,指定目标Service
                Intent intent = new Intent(ServiceActivity.this, MusicService.class);

                // 根据播放状态切换:未播放→启动Service(播放);已播放→停止Service(暂停)
                if (!MusicService.ispaly) {
                  startService(intent); // 启动Service,触发onStartCommand()
                  playBtn.setText("暂停音乐"); // 切换按钮文本
                } else {
                  stopService(intent); // 停止Service,触发onDestroy()
                  playBtn.setText("播放音乐"); // 切换按钮文本
                }
            }
      });
    }
}
</pre></div>
<p class="maodian"></p><h3>2.5 第五步:注册组件(AndroidManifest.xml)</h3>
<p>Service和Activity都需在清单文件中注册,否则无法使用。</p>
<div class="jb51code"><pre class="brush:xml;">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"&gt;

    &lt;application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:supportsRtl="true"
      android:theme="@style/Theme.MyApplication"&gt;

      &lt;!-- 注册Service:android:exported="true"允许外部启动(此处为应用内部使用,也可设为false) --&gt;
      &lt;service
            android:name=".MusicService"
            android:enabled="true"
            android:exported="true"&gt;&lt;/service&gt;

      &lt;!-- 注册Activity(启动页) --&gt;
      &lt;activity
            android:name=".ServiceActivity"
            android:exported="true"&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="android.intent.action.MAIN" /&gt;
                &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
            &lt;/intent-filter&gt;
      &lt;/activity&gt;
    &lt;/application&gt;

&lt;/manifest&gt;
</pre></div>
<p class="maodian"></p><h2>三、运行测试</h2>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025111808435286.png" /></p>
<p>到此这篇关于使用Android Service实现后台音乐播放功能的文章就介绍到这了,更多相关Android Service后台音乐播放内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Android基于service实现音乐的后台播放功能示例</li><li>Android利用Service开发简单的音乐播放功能</li><li>Android实现本地Service方法控制音乐播放</li><li>Android通过Service实现简单的音乐播放</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: 使用Android Service实现后台音乐播放功能