欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android通过startService播放背景音乐

程序员文章站 2023-12-14 21:59:16
关于startservice的基本使用概述及其生命周期可参见《android中startservice基本使用方法概述》。 本文通过播放背景音乐的简单示例,演示start...

关于startservice的基本使用概述及其生命周期可参见《android中startservice基本使用方法概述》。

本文通过播放背景音乐的简单示例,演示startservice的基本使用流程,具体内容如下

系统界面如下:

Android通过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;

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

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

上一篇:

下一篇: