Android--SoundPool
SoundPool
SoundPool(声音池),所处于"android.media.SoundPool"包下,主要用于播放一些较短的声音片段,支持从程序的资源或文件系统加载。与MediaPlayer相比,SoundPool的优势在于CPU的资源占用量低、反应延迟小,并且可以加载多个音频到SoundPool中,通过资源ID来管理。另外SoundPool还支持执行设置声音的品质、音量、播放比率等参数。
SoundPool提供一个构造函数,以下是它的完整签名:
SoundPool(int maxStreams,int streamType,int srcQuality)
通过上面的构造函数即可完成SoundPool的初始化,第一个参数为音频池最多支持装载多少个音频,就是音频池的大小;第二个参数指定声音的类型,在AudioManager类中以常量的形式定义,一般指定为AudioManager.STREAM_MUSIC即可;第三个参数为音频的质量,默认为0,这个参数为预留参数,现在没有实际意义,为扩展预留字段,一般传0即可。
对于一个音频池,涉及到音频的加载、播放、暂停、继续、释放资源等操作,SoundPool也为我们提供了相应的方法,其底层也是用C++编写的native方法。以下介绍一些常用的SoundPool方法:
- int load(Context context,int resId,int priority):从一个文件夹raw下装载一段音频资源,返回值为音频资源在SoundPool的ID。
- int load(String path,int priority):从一个资源文件的路径装载一段音频资源,返回值为音频资源在SoundPool的ID。
- final int play(int soundID,float leftVolume,float rightVolume,int priority,int loop,float rate):根据资源ID,播放一段音频资源。
- final void pause(int streamID):根据装载资源ID,暂停音频资源的播放。
- final void resume(int streamID):根据装载资源ID,继续播放暂停的音频资源。
- final void stop(int streamID):根据装载资源ID,停止音频资源的播放。
- final boolean unload(int soundID) :从音频池中卸载音频资源ID为soundID的资源。
- final void release():释放音频池资源。
上面方法无疑Load()和play()是最重要的,Load()具有多种重载方法,从参数名就可以看出是什么意思。这里讲解一下play()方法,soundID参数为资源ID;leftVolume和rightVolume个参数为左右声道的音量,从大到小取0.0f~1.0f之间的值;priority为音频质量,暂时没有实际意义,传0即可;loop为循环次数,0为播放一次,-1为无线循环,其他正数+1为播放次数,如传递3,循环播放4次;rate为播放速率,从大到小取0.0f~2.0f,1.0f为正常速率播放。
在使用load()装载音频的时候需要注意,load()方法是一个异步的方法,也就是说,在播放音频的时候,很可能此段音频还没有装载到音频池中,这里可以借助SoundPool的一个装载完成的监听事件SoundPool.setOnLoadCompleteListener来保证装载完成在播放声音。SoundPool.setOnLoadCompleteListener()需要实现一个SoundPool.OnLoadCompleteListener接口,其中需要实现onLoadComplete()方法,一下是onLoadComplete()方法的完整签名:
onLoadComplete(SoundPool soundPool, int sampleId, int status)
- soundPool:当前触发事件的声音池。
- sampleId:当前装载完成的音频资源在音频池中的ID。
- status:状态码,展示没有意义,为预留参数,会传递0。
使用SoundPool示例
上面已经介绍了SoundPool的使用所涉及到的内容,下面通过一个简单的示例来演示一下SoundPool的使用,播放的音频资源都是我从其他app中拷贝出来的,没有实际意义。示例中的注释写的比较全,这里不再累述了。
1 package cn.bgxt.soundpooldemo; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import android.media.AudioManager; 7 import android.media.SoundPool; 8 import android.media.SoundPool.OnLoadCompleteListener; 9 import android.os.Bundle; 10 import android.app.Activity; 11 import android.util.Log; 12 import android.view.View; 13 import android.view.View.OnClickListener; 14 import android.widget.Button; 15 import android.widget.Toast; 16 17 public class MainActivity extends Activity { 18 private Button btn_newqqmsg, btn_newweibontf, btn_newweibotoast; 19 private SoundPool pool; 20 private Map<String, Integer> poolMap; 21 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.activity_main); 26 btn_newqqmsg = (Button) findViewById(R.id.btn_newqqmsg); 27 btn_newweibontf = (Button) findViewById(R.id.btn_newweibontf); 28 btn_newweibotoast = (Button) findViewById(R.id.btn_newweibotoast); 29 30 poolMap = new HashMap<String, Integer>(); 31 // 实例化SoundPool,大小为3 32 pool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0); 33 // 装载音频进音频池,并且把ID记录在Map中 34 poolMap.put("newqqmsg", pool.load(this, R.raw.qqmsg, 1)); 35 poolMap.put("newweibontf", pool.load(this, R.raw.notificationsound, 1)); 36 poolMap.put("newweibotoast", pool.load(this, R.raw.newblogtoast, 1)); 37 38 pool.setOnLoadCompleteListener(new OnLoadCompleteListener() { 39 40 @Override 41 public void onLoadComplete(SoundPool soundPool, int sampleId, 42 int status) { 43 // 每次装载完成均会回调 44 Log.i("main", "音频池资源id为:" + sampleId + "的资源装载完成"); 45 // 当前装载完成ID为map的最大值,即为最后一次装载完成 46 if (sampleId == poolMap.size()) { 47 Toast.makeText(MainActivity.this, "加载声音池完成!", 48 Toast.LENGTH_SHORT).show(); 49 btn_newqqmsg.setOnClickListener(click); 50 btn_newweibontf.setOnClickListener(click); 51 btn_newweibotoast.setOnClickListener(click); 52 // 进入应用播放四次声音 53 pool.play(poolMap.get("newweibotoast"), 1.0f, 1.0f, 0, 3, 54 1.0f); 55 } 56 } 57 }); 58 } 59 60 private View.OnClickListener click = new OnClickListener() { 61 62 @Override 63 public void onClick(View v) { 64 65 switch (v.getId()) { 66 case R.id.btn_newqqmsg: 67 if (pool != null) { 68 pool.play(poolMap.get("newqqmsg"), 1.0f, 1.0f, 0, 0, 1.0f); 69 } 70 break; 71 case R.id.btn_newweibontf: 72 if (pool != null) { 73 pool.play(poolMap.get("newweibontf"), 1.0f, 1.0f, 0, 0, 74 1.0f); 75 } 76 break; 77 case R.id.btn_newweibotoast: 78 if (pool != null) { 79 pool.play(poolMap.get("newweibotoast"), 1.0f, 1.0f, 0, 0, 80 1.0f); 81 } 82 break; 83 default: 84 break; 85 } 86 } 87 }; 88 89 @Override 90 protected void onDestroy() { 91 // 销毁的时候释放SoundPool资源 92 if (pool != null) { 93 pool.release(); 94 pool = null; 95 } 96 super.onDestroy(); 97 } 98 }
效果展示:
SoundPool使用的注意事项
因为SoundPool的一些设计上的BUG,从固件版本1.0开始就有些没有修复的,以后应该会慢慢修复。这里简单提一下:
- 虽然SoundPool可以装载多个音频资源,但是最大只能申请1MB的内存空间,这就意味着只能用使用它播放一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。
- SoundPool提供的pause()、resume()、stop()最好不要轻易使用,因为它有时候会使程序莫名其妙的终止,如果使用,最好做大量的测试。而且有时候也不会立即终止播放声音,而是会等缓冲区的音频数据播放完才会停止。
- 虽然SoundPool比MediaPlayer的效率好,但也不是绝对不存在延迟的问题,尤其在那些性能不太好的手机中,SoundPool的延迟问题会更严重,但是现在一般的手机配置,那一点的延迟还是可以接受的。
源码下载
总结
本篇博客介绍了SoundPool的使用,虽然SoundPool还有一些不足的地方,当时对于应用中一些简短的特效音,如按键音、短消息音,或者一些游戏中密集的声音,如射击的枪声,爆破的声音等。都是可以使用SoundPool的,效率会比使用MediaPlayer要高的多。
本文转自承香墨影博客园博客,原文链接:http://www.cnblogs.com/plokmju/p/android_SoundPool.html,如需转载请自行联系原作者
Android--SoundPool相关推荐
- Android SoundPool.play方法的音量与系统音量的关系
Android中播放音频,除了使用MediaPlayer,还可以使用SoundPool.SoundPool使用音效池的概念来管理多个短促的音效,对于需要短促的提示音的场景特别合适. 通常调用Sound ...
- Android SoundPool 的简单使用
2019独角兽企业重金招聘Python工程师标准>>> 之前只知道Android中可以用MediapLayer播放音乐,原来今天才发现可以用SoundPool,用SoundPool可 ...
- Android ——SoundPool播放音频
SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作.但是这里如果音效文件过大没有载入完成,我们调用play方法时可能产生严重的后果,这里Android SDK提供了一个Sound ...
- android SoundPool 音效播放
音效播放: 资源文件: res/raw/filename 声音池类:SoundPool sp = new SoundPool(同时最大播放个数,AudioManager.STREAM_MUSIC,0) ...
- Android SoundPool播放音效详细步骤
MediaPlayer虽然也能播放音频,但是它有资源占用量较高,延迟时间较长,不支持多个音频同时播放等缺点,这些缺点决定MediaPlayer在某些场合的使用情况不会很理想,例如在对时间精准度要求相对 ...
- android soundpool设置音量,Android SoundPool.play方法的音量与系统音量的关系
Android中播放音频,除了使用MediaPlayer,还可以使用SoundPool.SoundPool使用音效池的概念来管理多个短促的音效,对于需要短促的提示音的场景特别合适. 通常调用Sound ...
- Android SoundPool插入耳机后依然有外放声音
使用soundPool播放声音,当手机已经接通耳机时,还会有外放声音,是因为在初始化soundpool是用的流类型(streamType)导致的,有些流类型系统是一定会播放外放的,比如警告类型和响铃类 ...
- android离线语音开发,Android应用开发之Android 云之声离线语音合成
本文将带你了解Android应用开发之Android 云之声离线语音合成,希望本文对大家学Android有所帮助. 离线语音解析 public class SpeechUtilOffline impl ...
- android播放音乐权限,android开发播放音乐需要声明什么权限
android开发播放音乐需要声明什么权限以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! android开发播放音乐需要 ...
- 视频和语音播放(进行中)
点播,直播,VR(录制音频和视频,在线的和本地的),视频播放器和音乐播放器(播放音乐和视频),视频和语音 VideoView并不是支持播放所有格式的视频,它仅支持mp4和3gp格式的文件,实际上它的本 ...
最新文章
- 终于好像懂motan了!!!
- Ubuntu 12.10 安装JDK、Hadoop全过程
- FreeBSD portupgrade升级你的FreeBSD软件[zt]
- 最难学编程语言排汗榜
- 电子测量与仪器第四版pdf_准确选择表面粗糙度仪的测量参数应该从哪些地方着手好【电子仪器吧】...
- mysql dump 数据时间_使用mysqldump备份数据及做时间点还原测试步骤
- “此网站使用的安全性配置已过时,这可能会导致您的信息(例如密码、消息或信用卡卡号)”
- 【MySQL数据库开发之四】MySQL 处理模式/常用查询/模式匹配等(下)
- 使用VisualStudio或VisualStudio Code作为代码比较工具
- 别人的一句话影响了我好几年
- ctbs mysql_C/C++/Java
- 网站无法打开显示阻断页面的解决方法
- 使用 Sublime 比较文档差异
- SCHTASKS windows计划任务
- layui中如何让多个控件在一行显示
- Jess的一些使用示例
- background: #ff0000 url(/i/eg_bg_03.gif) ; 图片 + 颜色
- c# Winform 程序嵌入PPT
- adb命令刷入kingroot_自己制作可永久伪root精简rom包及刷入教程
- python之turtle风轮绘制
热门文章
- 用深层神经网络解释大脑的运作
- 《WeCity未来城市2.0白皮书》全文发布
- AI解读医学影像能力超越人类?BMJ综述:此类研究大多存在偏差
- 聚焦第三届世界智能大会|大佬们讲了哪些干货?
- 李彦宏/王坚/王传福等上榜“中国工程院2019院士增选候选人”引争议,实至名归吗?...
- 关于未来的10点核心思考
- 科学家发现新的人类脑细胞,或可解答一个难题
- 2030全球新出行产业报告:2.2万亿美元蛋糕将这样分
- 华为、阿里员工跳槽至微软受抵制,微软当事人称:只是玩梗
- 来了个假阿里? | 每日趣闻