展会信息港展会大全

android开发中如何实现异步背景音乐播放
来源:互联网   发布日期:2016-01-19 12:01:49   浏览:1978次  

导读:在Android游戏开发中我们必须考虑背景音乐播放问题,在Android平台中提供了MediaPlayer类可以播放声音,但是游戏除了播放音乐外 还需要考虑画面的流畅性,以及多种音效同时播放,所以必须用到Android多线程机制 ...

在Android游戏开发中我们必须考虑背景音乐播放问题,在Android平台中提供了MediaPlayer类可以播放声音,但是游戏除了播放音乐外 还需要考虑画面的流畅性,以及多种音效同时播放,所以必须用到Android多线程机制和异步音效播放。Android SDK从1.0开始就提供了AsyncPlayer类,这里我们为了根据我们自己的需要可以派生或修改出更灵活的播放类。

进行Android游戏开发时,背景音乐的播放几乎是不得不考虑的问题,Android SDK提供了MediaPlayer类来播放声音,但还要充分考虑到它与画面的协调,画面的流畅性,多种音效同时播放等问题,这样就必须使用 Android多线程机制和异步音乐播放。

从Android SDK 1.0开始就提供了AsyncPlayer类,我们在使用它时可以根据需要派生出子类,以更灵活的实现异步播放功能。

import android.content.Context;

import android.net.Uri;

import android.os.PowerManager;

import android.os.SystemClock;

import android.util.Log;

import java.io.IOException;

import java.lang.IllegalStateException;

import java.util.LinkedList;

public class AsyncPlayer {

private static final int PLAY = 1;

private static final int STOP = 2;

private static final boolean mDebug = false;

private static final class Command {

int code;

Context context;

Uri uri;

boolean looping;

int stream;

long requestTime;

public String toString() {

return "{ code=" + code + " looping=" + looping + " stream=" + stream

+ " uri=" + uri + " }";

}

}

private LinkedList<Command> mCmdQueue = new LinkedList();//用一个链表保存播放参数队列

private void startSound(Command cmd) {

try {

MediaPlayer player = new MediaPlayer();

player.setAudioStreamType(cmd.stream);

player.setDataSource(cmd.context, cmd.uri);//设置媒体源,这里Android123提示大家本类的public void play (Context context, Uri uri, boolean looping, int stream) 类第二个参数Uri为媒体位置。

player.setLooping(cmd.looping);

player.prepare();

player.start();

if (mPlayer != null) {

mPlayer.release();

}

mPlayer = player;

}

catch (IOException e) {

Log.w(mTag, "error loading sound for " + cmd.uri, e);

} catch (IllegalStateException e) {

Log.w(mTag, "IllegalStateException (content provider died?) " + cmd.uri, e);

}

}

private final class Thread extends java.lang.Thread {//通过多线程方式不阻塞调用者

Thread() {

super("AsyncPlayer-" + mTag);

}

public void run() {

while (true) {

Command cmd = null;

synchronized (mCmdQueue) {//同步方式执行

cmd = mCmdQueue.removeFirst();

}

switch (cmd.code) {

case PLAY:

startSound(cmd);

break;

case STOP:

if (mPlayer != null) {

mPlayer.stop();

mPlayer.release();

mPlayer = null;

} else {

Log.w(mTag, "STOP command without a player");

}

break;

}

synchronized (mCmdQueue) {

if (mCmdQueue.size() == 0) {

mThread = null;

releaseWakeLock();

return;

}

}

}

}

}

private String mTag;

private Thread mThread;

private MediaPlayer mPlayer;

private PowerManager.WakeLock mWakeLock;

private int mState = STOP;

public AsyncPlayer(String tag) {

if (tag != null) {

mTag = tag;

} else {

mTag = "AsyncPlayer";

}

}

public void play(Context context, Uri uri, boolean looping, int stream) {

Command cmd = new Command();

cmd.requestTime = SystemClock.uptimeMillis(); //这里为了测试性能,传递了开始执行前的系统tickcount计时器值

cmd.code = PLAY;

cmd.context = context;

cmd.uri = uri;

cmd.looping = looping;

cmd.stream = stream;

synchronized (mCmdQueue) {

enqueueLocked(cmd);

mState = PLAY;

}

}

public void stop() {

synchronized (mCmdQueue) {

if (mState != STOP) {

Command cmd = new Command();

cmd.requestTime = SystemClock.uptimeMillis();

cmd.code = STOP;

enqueueLocked(cmd);

mState = STOP;

}

}

}

private void enqueueLocked(Command cmd) {

mCmdQueue.add(cmd);

if (mThread == null) {

acquireWakeLock();

mThread = new Thread();

mThread.start();

}

}

// 一般对于Android游戏而言下面的代码不用考虑,一般用户都在交互操作,不会出现屏幕锁问题

public void setUsesWakeLock(Context context) {//电源管理wakelock处理

if (mWakeLock != null || mThread != null) {

throw new RuntimeException("assertion failed mWakeLock=" + mWakeLock

+ " mThread=" + mThread);

}

PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);

mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);

}

private void acquireWakeLock() {//加锁

if (mWakeLock != null) {

mWakeLock.acquire();

}

}

private void releaseWakeLock() { //解锁

if (mWakeLock != null) {

mWakeLock.release();

}

}

}

赞助本站

人工智能实验室

相关热词: 背景音乐 异步 播放

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港