软件应用教程

Android游戏开发之旅16 异步音乐播放 Android开发技术

Android游戏开发之旅16 异步音乐播放 Android开发技术

  在Android游戏开发中我们必须考虑背景音乐播放问题,在Android平台中提供了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();
        }
    }
}

 

软件应用教程

更多有关于 软件应用教程

如何利用火车采集软件采集58招聘信息_爬虫软件技术与爬虫软件网页数据采集器门户

什么是火车采集器 如何使用火车采集器软件_爬虫软件技术与爬虫软件网页数据采集器门户

如何使用火车采集器制作zencart数据包来进行批量导入商品_爬虫软件技术与爬虫软件网页数据采集器门户

火车头采集器的DedeCMS5.7文章免登陆发布接口_爬虫软件技术与爬虫软件网页数据采集器门户

火车头采集器如何把浏览器里面的cookie到火车头采集器里面_爬虫软件技术与爬虫软件网页数据采集器门户

火车头采集器教程之如何通过fiddler获取cookie简单教程_爬虫软件技术与爬虫软件网页数据采集器门户

火车头采集器FTP设置 图片下载上传的路径的设置_爬虫软件技术与爬虫软件网页数据采集器门户

火车头采集器文件图片下载路径设置简易说明_爬虫软件技术与爬虫软件网页数据采集器门户

火车采集器采集淘宝天猫商品采集多页获取宝贝详细教程_爬虫软件技术与爬虫软件网页数据采集器门户

本人擅长Ai、Fw、Fl、Br、Ae、Pr、Id、Ps等软件的安装与卸载,精通CSS、JavaScript、PHP、ASP、C、C++、C#、Java、Ruby、Perl、Lisp、Python、Objective-C、ActionScript、Pascal等单词的拼写,熟悉Windows、Linux、OS X、Android、iOS、WP8等系统的开关机。

通过下面的方式来联系我们:

电邮:138762189@qq.com

联系QQ:点击这里给我发消息

官方站:www.tadke.com

※ ※ 联系请加我的企鹅号 ※※

※ ※技术支持请微信联系站长 ※※

Copyright © 2016 Tadke.com. Powered by Wordpress.