<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Cyh的博客

    Email:kissyan4916@163.com
    posts - 26, comments - 19, trackbacks - 0, articles - 220

    Android游戲開發之旅(十六) 異步音樂播放

    Posted on 2010-12-03 10:29 啥都寫點 閱讀(695) 評論(0)  編輯  收藏 所屬分類: Android

    在Android游戲開發中我們必須考慮背景音樂播放問題,在Android平臺中提供了MediaPlayer類可以播放聲音,但是游戲除了播放音樂外還需要考慮畫面的流暢性,以及多種音效同時播放,所以必須用到Android多線程機制和異步音效播放。Android SDK從1.0開始就提供了AsyncPlayer類,這里我們為了根據我們自己的需要可以派生或修改出更靈活的播放類。

    view plaincopy to clipboardprint?
    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();  
            }  
        } 
    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游戲而言下面的代碼不用考慮,一般用戶都在交互操作,不會出現屏幕鎖問題

    view plaincopy to clipboardprint?
    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();  
            }  
        }  

     

    本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034662.aspx



                                                                                                           --    學海無涯
            

    主站蜘蛛池模板: 中文文字幕文字幕亚洲色| 毛片亚洲AV无码精品国产午夜| 精品视频免费在线| 好先生在线观看免费播放| 亚洲一区动漫卡通在线播放| 最近最新高清免费中文字幕| 亚洲欧洲国产经精品香蕉网| 精品无码免费专区毛片| 亚洲人成影院在线高清| 午夜时刻免费入口| 婷婷亚洲综合一区二区| 亚洲高清最新av网站| 一级毛片a免费播放王色电影 | 2021在线永久免费视频| 亚洲综合在线成人一区| 999国内精品永久免费视频| www.亚洲日本| 国产免费私拍一区二区三区| 免费精品国产自产拍在线观看| 亚洲精品久久久www| 在线涩涩免费观看国产精品| 亚洲高清日韩精品第一区| 无码视频免费一区二三区| 国产精品亚洲一区二区三区在线观看 | 美女的胸又黄又www网站免费| 亚洲成a人一区二区三区| 99在线热播精品免费99热| 久久久久亚洲AV无码网站| 成年网站免费视频A在线双飞| 亚洲av无码av在线播放| 久久精品国产亚洲一区二区三区| 成全高清在线观看免费| 亚洲av专区无码观看精品天堂| 看全色黄大色大片免费久久 | 久久免费观看国产精品| 亚洲精品第一国产综合境外资源| 精品久久久久久无码免费| 亚洲视频中文字幕在线| 日本xxwwxxww在线视频免费| 国产免费阿v精品视频网址| 亚洲国产成人99精品激情在线|