android.media.AsyncPlayer

类概述

        AsyncPlayer是android实现异步音乐播放的一个类,它将要播放的媒体文件封装成内部类Command。为了实现多个音乐播放,所有command都加在了 LinkedList中,当调用play或者stop方法的时候,会根据参数封装成一个command对象,启动一个thread,thread中会把LinkedList的第一个command弹出,根据command的code去判断是要播放还是停止,播放调用startSound()方法,停止则释放所有资源,当LinkedList中没有command,线程便停止。

        播放一个连续(多个)的音频URLs,但那些任务较重的工作在另外的线程中完成,所以任何预处理或加载的延迟都不阻碍线程调用。

import android.content.Context;
import android.media.MediaPlayer;
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 mCmdQueue = new LinkedList();

	private void startSound(Command cmd) {

		try {
			MediaPlayer player = new MediaPlayer();
			player.setAudioStreamType(cmd.stream);
			player.setDataSource(cmd.context, cmd.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 = (Command) 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();
		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();
		}
	}

	public void setUsesWakeLock(Context context) {
		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();
		}
	}
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值