<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 啥都寫點 閱讀(685) 評論(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麻豆| 人人玩人人添人人澡免费| 一级毛片免费视频| 亚洲狠狠婷婷综合久久久久| 日韩毛片在线免费观看| 日本视频一区在线观看免费| 亚洲天堂一区二区| 97视频免费观看2区| 久久丫精品国产亚洲av| 99国产精品视频免费观看| 亚洲日韩精品国产3区| 日日AV拍夜夜添久久免费| 国产成人亚洲精品播放器下载| 吃奶摸下高潮60分钟免费视频| 日韩在线观看视频免费| 亚洲白色白色在线播放| 成人毛片18女人毛片免费| 亚洲AV无码资源在线观看| 四虎影视精品永久免费| 一区在线免费观看| 亚洲AV无码不卡在线播放| 永久免费在线观看视频| 最新国产成人亚洲精品影院| 日韩精品视频免费观看| 免费无码VA一区二区三区| 男人j进女人p免费视频| 国产精品亚洲片夜色在线| 国产精品亚洲аv无码播放| 免费看一级做a爰片久久| 久草免费在线观看视频| 久久亚洲AV成人无码国产最大| 亚洲男人第一av网站| 国产精品V亚洲精品V日韩精品| 久久免费观看国产精品88av| 黄色大片免费网站| 亚洲一区二区三区日本久久九| 亚洲国产aⅴ综合网| 久久精品一本到99热免费| 亚洲熟妇自偷自拍另欧美| 国产亚洲精品自在线观看| 凹凸精品视频分类国产品免费|