自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android游戲開發(fā)之十五:如何實(shí)現(xiàn)異步音樂播放

移動(dòng)開發(fā) Android 游戲開發(fā)
在Android游戲開發(fā)中我們必須考慮背景音樂播放問題,在Android平臺(tái)中提供了MediaPlayer類可以播放聲音,但是游戲除了播放音樂外還需要考慮畫面的流暢性,以及多種音效同時(shí)播放,所以必須用到Android多線程機(jī)制和異步音效播放。Android SDK從1.0開始就提供了AsyncPlayer類,這里我們?yōu)榱烁鶕?jù)我們自己的需要可以派生或修改出更靈活的播放類。

進(jìn)行Android游戲開發(fā)時(shí),背景音樂的播放幾乎是不得不考慮的問題,Android SDK提供了MediaPlayer類來播放聲音,但還要充分考慮到它與畫面的協(xié)調(diào),畫面的流暢性,多種音效同時(shí)播放等問題,這樣就必須使用Android多線程機(jī)制和異步音樂播放。

從Android SDK 1.0開始就提供了AsyncPlayer類,我們?cè)谑褂盟鼤r(shí)可以根據(jù)需要派生出子類,以更靈活的實(shí)現(xiàn)異步播放功能。

  1. import android.content.Context;    
  2. import android.net.Uri;    
  3. import android.os.PowerManager;    
  4. import android.os.SystemClock;    
  5. import android.util.Log;    
  6. import java.io.IOException;    
  7. import java.lang.IllegalStateException;    
  8. import java.util.LinkedList;    
  9. public class AsyncPlayer {    
  10.     private static final int PLAY = 1;    
  11.     private static final int STOP = 2;    
  12.     private static final boolean mDebug = false;    
  13.     private static final class Command {    
  14.         int code;    
  15.         Context context;    
  16.         Uri uri;    
  17.         boolean looping;    
  18.         int stream;    
  19.         long requestTime;    
  20.         public String toString() {    
  21.             return "{ code=" + code + " looping=" + looping + " stream=" + stream    
  22.                     + " uri=" + uri + " }";    
  23.         }    
  24.     }    
  25.     private LinkedList<Command> mCmdQueue = new LinkedList();  //用一個(gè)鏈表保存播放參數(shù)隊(duì)列    
  26.     private void startSound(Command cmd) {    
  27.         try {    
  28.             MediaPlayer player = new MediaPlayer();    
  29.             player.setAudioStreamType(cmd.stream);    
  30.             player.setDataSource(cmd.context, cmd.uri);  //設(shè)置媒體源,這里Android123提示大家本類的public void play (Context context, Uri uri, boolean looping, int stream) 類第二個(gè)參數(shù)Uri為媒體位置。    
  31.             player.setLooping(cmd.looping);    
  32.             player.prepare();    
  33.             player.start();    
  34.             if (mPlayer != null) {    
  35.                 mPlayer.release();    
  36.             }    
  37.             mPlayer = player;    
  38.           }    
  39.         catch (IOException e) {    
  40.             Log.w(mTag, "error loading sound for " + cmd.uri, e);    
  41.         } catch (IllegalStateException e) {    
  42.             Log.w(mTag, "IllegalStateException (content provider died?) " + cmd.uri, e);    
  43.         }    
  44.     }    
  45.     private final class Thread extends java.lang.Thread {   //通過多線程方式不阻塞調(diào)用者    
  46.         Thread() {    
  47.             super("AsyncPlayer-" + mTag);    
  48.         }    
  49.         public void run() {    
  50.             while (true) {    
  51.                 Command cmd = null;    
  52.                 synchronized (mCmdQueue) {   //同步方式執(zhí)行    
  53.                         cmd = mCmdQueue.removeFirst();    
  54.                 }    
  55.                 switch (cmd.code) {    
  56.                 case PLAY:    
  57.                                  startSound(cmd);    
  58.                     break;    
  59.                 case STOP:    
  60.                     if (mPlayer != null) {    
  61.                                          mPlayer.stop();    
  62.                         mPlayer.release();    
  63.                         mPlayer = null;    
  64.                     } else {    
  65.                         Log.w(mTag, "STOP command without a player");    
  66.                     }    
  67.                     break;    
  68.                 }    
  69.                 synchronized (mCmdQueue) {    
  70.                     if (mCmdQueue.size() == 0) {    
  71.                 
  72.                         mThread = null;    
  73.                         releaseWakeLock();    
  74.                         return;    
  75.                     }    
  76.                 }    
  77.             }    
  78.         }    
  79.     }    
  80.     private String mTag;    
  81.     private Thread mThread;    
  82.     private MediaPlayer mPlayer;    
  83.     private PowerManager.WakeLock mWakeLock;    
  84.     private int mState = STOP;    
  85.     public AsyncPlayer(String tag) {    
  86.         if (tag != null) {    
  87.             mTag = tag;    
  88.         } else {    
  89.             mTag = "AsyncPlayer";    
  90.         }    
  91.     }    
  92.     public void play(Context context, Uri uri, boolean looping, int stream) {    
  93.         Command cmd = new Command();    
  94.         cmd.requestTime = SystemClock.uptimeMillis(); //這里為了測(cè)試性能,傳遞了開始執(zhí)行前的系統(tǒng)tickcount計(jì)時(shí)器值    
  95.         cmd.code = PLAY;    
  96.         cmd.context = context;    
  97.         cmd.uri = uri;    
  98.         cmd.looping = looping;    
  99.         cmd.stream = stream;    
  100.         synchronized (mCmdQueue) {    
  101.             enqueueLocked(cmd);    
  102.             mState = PLAY;    
  103.         }    
  104.     }    
  105.     public void stop() {    
  106.         synchronized (mCmdQueue) {    
  107.                  if (mState != STOP) {    
  108.                 Command cmd = new Command();    
  109.                 cmd.requestTime = SystemClock.uptimeMillis();    
  110.                 cmd.code = STOP;    
  111.                 enqueueLocked(cmd);    
  112.                 mState = STOP;    
  113.             }    
  114.         }    
  115.     }    
  116.     private void enqueueLocked(Command cmd) {    
  117.         mCmdQueue.add(cmd);    
  118.         if (mThread == null) {    
  119.             acquireWakeLock();    
  120.             mThread = new Thread();    
  121.             mThread.start();    
  122.         }    
  123.     }    
  124.     // 一般對(duì)于Android游戲而言下面的代碼不用考慮,一般用戶都在交互操作,不會(huì)出現(xiàn)屏幕鎖問題    
  125.     public void setUsesWakeLock(Context context) {  //電源管理wakelock處理    
  126.         if (mWakeLock != null || mThread != null) {    
  127.                       throw new RuntimeException("assertion failed mWakeLock=" + mWakeLock    
  128.                     + " mThread=" + mThread);    
  129.         }    
  130.         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);    
  131.         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);    
  132.     }    
  133.     private void acquireWakeLock() {   //加鎖    
  134.         if (mWakeLock != null) {    
  135.             mWakeLock.acquire();    
  136.         }    
  137.     }    
  138.     private void releaseWakeLock() { //解鎖    
  139.         if (mWakeLock != null) {    
  140.             mWakeLock.release();    
  141.         }    
  142.     }    
  143. }   

 

責(zé)任編輯:閆佳明 來源: jizhuomi
相關(guān)推薦

2013-05-21 14:10:11

Android游戲開發(fā)SoundPool類同時(shí)多音效

2011-04-25 14:45:38

2013-05-21 13:55:51

Android游戲開發(fā)圖像漸變特效

2012-12-24 09:04:04

iOSUnity3D

2013-05-21 11:26:49

Android游戲開發(fā)Sensor感應(yīng)

2022-06-19 14:23:56

Linux

2013-05-21 11:20:37

Android游戲開發(fā)View手勢(shì)識(shí)別

2022-12-19 16:56:48

游戲開發(fā)鴻蒙

2011-08-29 09:49:35

LuaAndroid游戲

2021-05-31 07:30:47

Connectsocket函數(shù)

2013-05-20 17:48:20

2013-05-21 09:56:15

2013-05-21 10:42:48

Android游戲開發(fā)Bitmap位圖旋轉(zhuǎn)

2013-05-21 11:24:07

Android游戲開發(fā)Sensor重力感應(yīng)

2019-01-02 15:15:55

游戲開發(fā)音樂工具命令

2021-08-24 15:13:06

鴻蒙HarmonyOS應(yīng)用

2010-12-01 14:34:59

AsyncTask異步處理任務(wù)Android

2011-04-06 10:03:45

谷歌云計(jì)算Android音

2017-03-01 14:01:31

android多媒體音樂代碼

2017-07-06 17:39:53

JavaScript開發(fā)程序員
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)