首页 > 其他分享 >Android开发之SoundPool

Android开发之SoundPool

时间:2023-07-28 19:07:10浏览次数:36  
标签:int sndPool SoundPool 开发 import Android 播放 android


忙了两天终于得空写点东西,感慨良多,今天主要总结一下,这个SoundPool的使用,以及注意事项。

首先,SoundPool的定位,她是一个音效播放的执行者,这跟MediaPlayer的最终效果是一样的,她们都是用来播放音乐的。

今天,我们主讲一下,SoundPool这个类。附带的说一说她与MediaPlayer的区别。

下面我们说一下SoundPool播放音频的实现步骤:

1. new出一个实例 ;


new SoundPool(int maxStream, int streamType, int srcQuality);



maxStream —— 同时播放的流的最大数量

streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)

srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值

比如说,

new SoundPool(4, AudioManager.STREAM_MUSIC, 100);

创建了一个最多支持4个流同时播放的,类型标记为音乐的SoundPool。

2.加载

一般把多个声音放到HashMap中去,比如
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
soundPoolMap = new HashMap<Integer, Integer>();
soundPoolMap.put(1, soundPool.load(this, R.raw.ring, 1));

当然,我们也可以加载单个的Music,那我们怎么实现播放指定的Music呢?

有关载入音效的方法,有以下几种方法:


1
 int load(Context context, int resId, int priority) //从APK资源载入(就是说,在你码代码的时候工程中的文件。比如,我在res/raw这个文件夹中放了一个ring.mp3,那,resIdential就是 R.raw.ring)
 
   
 2
 int load(FileDescriptor fd, long offset, long length, int priority) //从FileDescriptor对象载入
 
   
 3
 int load(AssetFileDescriptor afd, int priority) //从Asset对象载入
 
   
 4
 int load(String path, int priority) //从完整文件路径名载入
 
   
 5

 
   
 6
 所有的最后一个参数 priority 是优先级。这里用于播放多个文件时,系统会优先处理。


3,播放

play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate);

其中soundID,就是刚刚load方法得到的那个int型参数,leftVolume和rightVolume表示左右音量,priority表示优先级,loop表示循环次数,rate表示速率,如
//速率最低0.5最高为2,1代表正常速度

sp.play(soundId, 1, 1, 0, 0, 1);




4,停止

停止可以使用 pause(int streamID) 方法,这里的streamID和soundID均在构造SoundPool类的第一个参数中指明了总数量,而id从0开始。

OK,这就是一个SoundPool的流程,可是,有人要问了,为什么我按这个流程写下来,却没有播放呢?

不饶弯子,因为,在play之前Soundpool没有初始化完毕,那我们如何知道,Soundpool的load已经完毕了呢?Android提供了检测是否初始化完毕的方法,SoundPool.OnLoadCompleteListener;但是这个方法是从SDK2.2才开始有的。所以找错之前,先看看自己的平台。。。
下面讲下两个播放形式的利弊:

一,使用MediaPlayer来播放音频文件存在一些不足:

例如:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。

这些缺点决定了MediaPlayer在某些场合的使用情况不会很理想,所有,一般的游戏开发都是用的Soundpool。

在没有了解Soundpool之前,我也是使用的普通的MediaPlayer进行文件播放,但这个方法不适合用于游戏开发,因为游戏里面经常要同时播放几个音乐文件,用过MediaPlayer的朋友都该知道,它是不支持实时播放多个声音的,而且还会出现或多或少的延迟,尤其是在快速连续播放声音(比如连续猛点按钮)时,会非常明显,长的时候会出现3~5秒的延迟,【使用MediaPlayer.seekTo() 这个方法来解决此问题】;

相对于使用SoundPool存在的一些问题:

1. SoundPool是为播放小文件而存在的。一般限定Soundpool播放文件的大小为1M。

2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。

3. 音频格式建议使用OGG格式。使用WAV格式的音频文件存放游戏音效,经过反复测试,在音效播放间隔较短的情况下会出现异常关闭的情况(有说法是SoundPool目前只对16bit的WAV文件有较好的支持)。后来将文件转成OGG格式,问题得到了解决。

4.在使用SoundPool播放音频的时候,如果在初始化中就调用播放函数进行播放音乐那么根本没有声音,不是因为没有执行,而是SoundPool需要一准备时间!这就是刚刚我们说的用OnLoadCompleteListener来解决的问题。如果你非得是1.6甚至更低的话,那建议在播放的时候,将play放到一个点击事件中去,当然在这个中也要注意一下两点。

a、 别忘记绑定操作! mp.setOnCompletionListener(this);

b、如果你设置了循环播放 mp.setLooping(true); 的话,那么永远都不会监听到播放完成的状态!!

下面分享一下源码,

 
  
  
 01
 import android.app.Activity;
 
   
 02
 import android.media.AudioManager;
 
   
 03
 import android.media.SoundPool;
 
   
 04
 import android.os.Bundle;
 
   
 05
 import android.os.Handler;
 
   
 06
 import android.os.Message;
 
   
 07
 import android.view.View;
 
   
 08
 import android.view.View.OnClickListener;
 
   
 09
 import android.widget.Button;
 
   
 10
 import android.media.SoundPool.OnLoadCompleteListener;</p>
 
   
 11
 public class DemoActivity extends Activity implements SoundPool.OnLoadCompleteListener{
 
   
 12

 
   
 13
 private Button button;
 
   
 14
 private SoundPool sndPool;
 
   
 15
 private int hitOkSfx;
 
   
 16
 private static final int SOUND_LOAD_OK = 1;
 
   
 17
 private final Handler mHandler = new MyHandler() ;
 
   
 18
 @Override
 
   
 19
 public void onCreate(Bundle savedInstanceState) {
 
   
 20
 super.onCreate(savedInstanceState);
 
   
 21
 setContentView(R.layout.main);
 
   
 22
 button = (Button)findViewById(R.id.button1);
 
   
 23
 sndPool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 0);
 
   
 24
 sndPool.setOnLoadCompleteListener(this);
 
   
 25
 hitOkSfx = sndPool.load(this, R.raw.ring, 1);
 
   
 26
 button.setOnClickListener(new OnClickListener() {
 
   
 27
 @Override
 
   
 28
 public void onClick(View v) {
 
   
 29
 // TODO Auto-generated method stub
 
   
 30
 sndPool.play(hitOkSfx, 10, 10, 0, 0, (float)1);//播放铃声
 
   
 31
 }
 
   
 32
 });
 
   
 33
 }
 
   
 34
 @Override
 
   
 35
 protected void onDestroy() {
 
   
 36
 // TODO Auto-generated method stub
 
   
 37
 sndPool.release();
 
   
 38
 sndPool.stop(hitOkSfx);
 
   
 39
 super.onDestroy();
 
   
 40

 
   
 41
 }
 
   
 42
 private class MyHandler extends Handler {
 
   
 43
 public void handleMessage(Message msg){
 
   
 44
 switch( msg.what){
 
   
 45
 case SOUND_LOAD_OK:
 
   
 46
 sndPool.play(hitOkSfx, 10, 10, 0, 0, (float)1);//播放铃声
 
   
 47
 break;
 
   
 48
 }
 
   
 49
 }
 
   
 50
 }
 
   
 51
 @Override
 
   
 52
 public void onl oadComplete(SoundPool soundPool, int sampleId, int status) {
 
   
 53
 // TODO Auto-generated method stub
 
   
 54
 Message msg = mHandler.obtainMessage(SOUND_LOAD_OK); ;
 
   
 55
 msg.arg1 = sampleId ;
 
   
 56
 mHandler.sendMessage(msg);
 
   
 57
 }
 
   
 58

 
   
 59
 }


这个就到这里了吧。。。

标签:int,sndPool,SoundPool,开发,import,Android,播放,android
From: https://blog.51cto.com/u_548275/6886115

相关文章

  • Android 中的 Service 全面总结
    Android中的Service全面总结rvice的种类 按运行地点分类:类别区别优点应用本地服务(Local)该服务依附在主进程上,服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多......
  • Android web services详细使用
    Android与服务器端数据交互(基于SOAP协议整合android+webservice)上一节中我们通过http协议,采用HttpClient向服务器端action请求数据。当然调用服务器端方法获取数据并不止这一种。WebService也可以为我们提供所需数据,那么什么是webService呢?,它是一种基于SAOP协议的远程调用标准,......
  • Android 资源和国际化 [复制链接]
    Android资源和国际化[复制链接]资源是您在代码中使用到的并且在编译时被打包进您的应用程序的附加文件。Android支持多种不同的文件,包括XML、PNG和JPEG文件。XML文件的格式决定于其描述的内容。这些文件将描述文件支持的类型、语法或格式。  处于加载效率的考虑,资源被从......
  • android services 使用
    Android之Services【Services】一个Service是一个应用程序组件,它能完成长时间运行的操作在后台,并且不提供用户接口。另一个应用程序组件能开启一个service并且它将继续运行在后台即使用户转换到另一个应用程序。额外的,一个组件可以被绑定到一个service来和它交......
  • Android应用性能优化之分析工具
    Android应用性能优化之分析工具上一次记录了解决过度绘制的过程,这一次,想先弄清个概念性的东西,就是如何判断顺不顺畅?这东西其实最初我自己也觉得有点废话,用起来会卡就明显是不顺畅咯。但这东西就跟我很想吐槽很多应用一样,明明那么卡还放出来一样的道理。......
  • Android多线程及异步处理问题
    1、问题提出1)为何需要多线程?2)多线程如何实现?3)多线程机制的核心是啥?4)到底有多少种实现方式?2、问题分析1)究其为啥需要多线程的本质就是异步处理,直观一点说就是不要让用户感觉到“很卡”。eg:你点击按钮下载一首歌,......
  • Android多文件上传的原理
    android上面图片的上传可以用apache包里面的httpclient和MultipartEntity来上传图片,这种的上传方式的话由于都封装好了所以看不到HTTP协议里面具体是怎样上传的;其实图片的上传还可以用Java自带的HttpURLConnection来做上传处理,例如有一个PHP写的接收图片的POST接口http://localho......
  • 上百个Android开源项目分享
    上百个Android开源项目分享,希望对android开发有帮助。AndroidPDF阅读器http://sourceforge.net/projects/andpdf/files/个人记账工具OnMyMeanshttp://sourceforge.net/projects/onmymeans/developAndroid电池监控AndroidBatteryDoghttp://sourceforge.net/projects/a......
  • Android开发者应该深入学习的10个…
    1.Android团队提供的示例项目 如果不是从学习AndroidSDK中提供的那些样例代码开始,可能没有更好的方法来掌握在Android这个框架上开发。由Android的核心开发团队提供了15个优秀的示例项目,包含了游戏、图像处理、时间显示、开始菜单快捷方式等。 地址:http://code.google.com/p/......
  • J2EE开发中Filter的奇妙作用
    Servlet2.3Filter1、ServletFilter概述凡是开发过J2EE的webapplication的人员都知道,经常需要处理以下几种情况:访问特定资源(Web页、JSP页、servlet)时的身份认证应用程序级的访问资源的审核和记录应用程序范围内对资源的加密......