soundpool 过时初始化的过程是同步的。对吗

android(215)
一、SoundPool类简介与适用场合
&&&&&&& 1)SoundPool简介
&&&&&&& SoundPool类是Android用于管理和播放应用程序的音频资源的类。一个SoundPool对象可以看作是一个可以从APK中导入资源或者从文件系统中载入文件的样本集合。它利用MediaPlayer服务为音频解码为一个原始16位PCM流。这个特性使得应用程序可以进行流压缩,而无须忍受在播放音频时解压所带来的CPU负载和时延。
&&&&&&& 此外对于低延迟播放,SoundPool还可以管理多个音频流。当SoundPool对象构造时,maxStreams参数的设置表示的是在单一的SoundPool中,同一时间所能播放流的最大数量。利用SoundPool可以跟踪活跃的流的数量。如果其数量超过流的最大数目,SoundPool会基于优先级自动停止先前播放的流。限制流的最大数目,有助于减轻CPU的负荷,减少音频混合对视觉和UI性能的影响。
&&&&&&& 声音可以通过设置一个非零的循环价值循环。如果值为-1将导致声音永远循环。在这种情况下,应用程序必须明确地调用stop()函数,以停止声音。其他非零值将导致声音按指定数量的时间重复。
&&&&&&& 在SoundPool中,播放速率也可以改变。1.0的播放率可以使声音按照其原始频率(如果必要的话,将重新采样硬件输出频率)。而2.0的播放速率,可以使声音按照其原始频率的两倍播放。如果为0.5的播放率,则播放速率是原始频率的一半。播放速率的取值范围是0.5至2.0。
&&&&&&& 优先级的运行从低到高排列的。当用户调用play()函数时,如果活跃的流数目大于规定的maxStreams参数,流分配器将会结束优先级最低的流。如果有多条流都处于最低优先级,优先级系统将会选择关闭最老的流。
&&&&&&& 一旦声音被成功加载和播放,应用程序可以调用SoundPool.play()来触发的声音。播放过程中的流可又被暂停或继续播放。应用程序还可以通过调整播放率改变音高。
&&&&&&& 注意,由于资源的限制,流可以被停止,streamID是一个对特定流实例的引用。如果流被停止并且允许更高优先级的流播放,流就不再有效了。然而,应用程序允许调用没有错误的streamID方法。因为如果应用程序不需要关心流的生命周期,这可能有助于简化程序逻辑。
&&&&&&& 2)适用场合
&&&&&&& SoundPool在载入声音文件过程中,使用了单独的线程,不会对视觉和UI性能产生影响。但是由于SoundPool对载入声音文件大小有所限制,这就导致了如果SoundPool没有载入完成,而不能安全调用play方法。好在Android SDK提供了一个SoundPool.OnLoadCompleteListener类来帮助我们了解声音文件是否载入完成,用户只须重载 onLoadComplete(SoundPool soundPool, int sampleId, int status) 方法即可实现。
与MediaPlayer相比,MediaPlayer存在着资源占用量较高、延迟时间较长、不支持多个音频同时播放等缺点,但SoundPool本身由于内存资源申请有严格限制,所以在开发过程中,笔者建议尽量用SoundPool来播放一些较短的声音片段或者音效。  
二、使用SoundPool播放声音
&&&&&&& 1)SoundPool对象初始化
&&&&&&& 我们可以调用SoundPool的构造函数public SoundPool (int maxStreams, int streamType, int srcQuality)来初始化SoundPool对象。
&&&&&&& 其中参数说明如下:
&&&&&&& maxStreams:指定支持多少个声音,SoundPool对象中允许同时存在的最大流的数量。
&&&&&&& streamType:制定声音类型,流类型可以分为STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING,STREAM_MUSIC 和 STREAM_ALARM四种类型。在AudioManager中定义。
&&&&&&& srcQuality:指定声音品质(采样率变换质量)。目前没有用到,可以设为0。
&&&&&&& 2)载入声音资源
&&&&&&& 调用load方法载入声音资源,SoundPool提供了4个Load方法,比较常用的是以下两个:
&&&&&&& Public int load(Context context, int resId, int priority):从resId所对应的资源加载声音。
&&&&&&& Public int load(String path, int priority):从path对应的文件中加载声音。
&&&&&&& 上面两个方法中都有一个priority参数,该参数目前还没有任何作用,Android建议将该参数设置为1,保持和未来的兼容性。
&&&&&&& 同时,这两个方法加载声音之后,都会返回该声音的ID,以后程序就可以通过该声音的ID来播放指定声音。
&&&&&&& 3)播放控制
&&&&&&& 要播放SoundPool中的声音,须调用int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)方法。
&&&&&&& 其中参数说明如下:
&&&&&&& soundID:Load()函数返回的声音ID号。
&&&&&&& leftVolume:左声道音量设置。
&&&&&&& rightVolume:右声道音量设置。
&&&&&&& priority:指定播放声音的优先级,数值越高,优先级越大。
&&&&&&& loop:指定是否循环。-1表示无限循环,0表示不循环,其他值表示要重复播放的次数。
&&&&&&& rate:指定播放速率。1.0的播放率可以使声音按照其原始频率。而2.0的播放速率,可以使声音按照其原始频率的两倍播放。如果为0.5的播放率,则播放速率是原始频率的一半。播放速率的取值范围是0.5至2.0。
&&&&&&& 4)释放资源
&&&&&&& 播放结束,我们可以调用release()方法释放所有SoundPool对象占据的内存和资源。
&&&&&&& 5)实例分析
&&&&&&& 下面通过一个简单的Demo来分析一下SoundPool的用法,布局文件非常简单,不再给出代码。
&&&&&&& MainActivity.java的内容如下:
com.devdiv.test.soundpool_
java.util.HashM
android.app.A
android.media.AudioM
android.media.SoundP
android.os.B
android.view.V
android.view.View.OnClickL
android.widget.B
class MainActivity extends
Activity implements
OnClickListener {
&&&&&&& Button bombB
&&&&&&& Button shotB
&&&&&&& Button arrowB
&&&&&&& Button allB
&&&&&&& SoundPool mSoundPool =
&&&&&&& HashMap&Integer, Integer& soundMap =
new HashMap&Integer, Integer&();
&&& @Override
&&& public
void onCreate(Bundle savedInstanceState) {
&&&&&&& super.onCreate(savedInstanceState);
&&&&&&& setContentView(R.layout.activity_main);
&&&&&&& bombButton = (Button) findViewById(R.id.bomb);
&&&&&&& shotButton = (Button) findViewById(R.id.shot);
&&&&&&& arrowButton = (Button) findViewById(R.id.arrow);
&&&&&&& allButton = (Button) findViewById(R.id.all);
&&&&&&&&&&&&&&&
&&&&&&& mSoundPool =
new SoundPool(10, AudioManager.STREAM_SYSTEM,
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& soundMap.put(1
, mSoundPool.load(this, R.raw.bomb ,
&&&&&&&&&&&&&&& soundMap.put(2
, mSoundPool.load(this, R.raw.shot ,
&&&&&&&&&&&&&&& soundMap.put(3
, mSoundPool.load(this, R.raw.arrow ,
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& bombButton.setOnClickListener(this);
&&&&&&&&&&&&&&& shotButton.setOnClickListener(this);
&&&&&&&&&&&&&&& arrowButton.setOnClickListener(this);
&&&&&&&&&&&&&&& allButton.setOnClickListener(this);
&&&&&&& @Override
&&&&&&& public
void onClick(View v) {
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& switch
(v.getId()) {
&&&&&&&&&&&&&&& case
R.id.bomb:
&&&&&&&&&&&&&&&&&&&&&&& mSoundPool.play(soundMap.get(1),
&&&&&&&&&&&&&&&&&&&&&&& break;
&&&&&&&&&&&&&&& case
R.id.shot:
&&&&&&&&&&&&&&&&&&&&&&& mSoundPool.play(soundMap.get(2),
&&&&&&&&&&&&&&&&&&&&&&& break;
&&&&&&&&&&&&&&& case
R.id.arrow:
&&&&&&&&&&&&&&&&&&&&&&& mSoundPool.play(soundMap.get(3),
&&&&&&&&&&&&&&&&&&&&&&& break;
&&&&&&&&&&&&&&& case
&&&&&&&&&&&&&&&&&&&&&&& mSoundPool.play(soundMap.get(1),
&&&&&&&&&&&&&&&&&&&&&&& mSoundPool.play(soundMap.get(2),
&&&&&&&&&&&&&&&&&&&&&&& mSoundPool.play(soundMap.get(3),
&&&&&&&&&&&&&&& default:
&&&&&&&&&&&&&&&&&&&&&&& break;
&&&&&&&&&&&&&&& }
&&&&&&& 通常,为了更好地管理SoundPool所加载的每个声音的ID,程序一般会使用一个HashMap&Integer,Integer&对象来管理声音。按照上面的步骤初始化,载入声音,并且把按钮绑定监听器,点击按钮播放相应声音。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:300770次
积分:4460
积分:4460
排名:第4319名
原创:55篇
转载:641篇
评论:16条
(4)(8)(22)(8)(4)(17)(49)(57)(13)(11)(4)(1)(4)(16)(4)(1)(1)(7)(1)(4)(17)(3)(6)(11)(32)(8)(7)(12)(13)(24)(74)(162)(44)(51)Android的SoundPool种使用与利弊 - Android当前位置:& &&&Android的SoundPool种使用与利弊Android的SoundPool种使用与利弊&&网友分享于:&&浏览:55次Android的SoundPool类使用与利弊
在开发Android软件中我们可能经常需播放多媒体声音文件,一般使用MediaPlayer类但该类占用资源较多,对于游戏等应用可能不是很适合,这里Android123描述下SoundPool类。SoundPool类在SDK的android.media.SoundPool,顾名思义是声音池的意思。主要播放一些较短的声音片段,可以从程序的资源或文件系统加载,相对于MediaPlayer类可以做到使用较少的CPU资源和较短的反应延迟。SoundPool和其他声音播放类相比,其特点是可以自行设置声音的品质、音量、播放比率等参等。并且它可以同时管理多个音频流,每个流都有独自的ID,对某个音频流的管理都是通过ID进行的。SoundPool基本使用方法为:& 创建一个SoundPool对象:new SoundPool(int maxStreams, int streamType, int srcQuality);& 从资源或者文件载入音频流: load(Context& context, int resId, int priority);& 播放声音play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)import android.media.AudioMimport android.media.SoundPpublic class android123 extends Activity {private SoundPprivate int hitOkS&&& /** Called when the activity is first created. */&&& @Override&&& public void onCreate(Bundle savedInstanceState) {&&&&&&& super.onCreate(savedInstanceState);&&&&&&& setContentView(R.layout.main);//这里指定声音池的最大音频流数目为10,//声音品质为5大家可以自己测试感受下效果&&&&&&& snd = new SoundPool(10, AudioManager.STREAM_SYSTEM,5);& //载入音频流hitOkSfx = snd.load(context, R.raw.ok, 0);Button btn=(Button)findViewById(R.id.btn);btn.setOnClickListener(new View.OnClickListener(){public void onClick(View v){// play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)//播放音频,可以对左右音量分别设置,还可以设置优先级,循环次数以及速率//速率最低0.5最高为2,1代表正常速度&&&&&&&& snd.play(hitOkSfx, 1, 1, 0, 0, 1);});}}这样我们就可以使用SoundPool简单的播放一个声音了。相信不少朋友已经想试一试了,可是SoundPool并非尽善尽美的。就现在已知的资料来说,SoundPool有一些设计上的BUG,从固件版本1.0开始有些都没有修复,我们在使用中应该小心再小心。相信将来Google会修复这些问题,但我们最好还是列出来:1. SoundPool最大只能申请1M的内存空间,这就意味着我们只能用一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。Android开发网建议使用这两个方法的时候尽可能多做测试工作,还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。3. SoundPool的效率问题。其实SoundPool的效率在这些播放类中算是很好的了,但是有的朋友在G1中测试它还是有100ms左右的延迟,这可能会影响用户体验。也许这不能管SoundPool本身,因为到了性能比较好的Droid中这个延迟就可以让人接受了。在现阶段SoundPool有这些缺陷,但也有着它不可替代的优点,基于这些我们建议大在如下情况中多使用SoundPool:1.应用程序中的声效(按键提示音,消息等)2.游戏中密集而短暂的声音(如多个飞船同时爆炸),当然大家还可以想到更多的使用方法。
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有Android常用控件之SoundPool
播放一般较大内存的音乐,可以用MediaPlayer,但实际中,那些小型的音频或(如:提示音)或者对响应速度要求较高的音频就不适合用MediaPlayer,MediaPlayer的响应需要一定时间,而且需要添加线程。
SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作。但是这里如果音效文件过大没有载入完成,我们调用play方法时可能产生严重的后果,这里 SDK提供了一个SoundPool.OnLoadCompleteListener类来帮助我们了解媒体文件是否载入完成,我们重载 onLoadComplete(SoundPool soundPool, int sampleId, int status) 方法即可获得。 从上面的onLoadComplete方法可以看出该类有很多参数,比如类似id,是的SoundPool在load时可以处理多个媒体一次初始化并放入内存中,这里效率比MediaPlayer高了很多。 SoundPool类支持同时播放多个音效,这对于游戏来说是十分必要的,而MediaPlayer类是同步执行的只能一个文件一个文件的播放。
SDK21版本后,SoundPool的创建发生了很大变化,所以在开发中需要进行版本控制。
sdk21之前:
创建SoundPool:
SoundPool(int maxStream, int streamType, int srcQuality)
maxStream && 同时播放的流的最大数量
streamType && 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
srcQuality && 采样率转化质量,当前无效果,使用0作为默认
加载音频:
如果要加载多个音频,需要用到HashMap等,单个音频,直接传入load()方法即可
soundPool的加载 :
int load(Context context, int resId, int priority) //从APK资源载入
int load(FileDescriptor fd, long offset, long length, int priority) //从FileDescriptor对象载入
int load(AssetFileDescriptor afd, int priority) //从Asset对象载入 int load(String path, int priority) //从完整文件路径名载入
播放音频:
play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
其中leftVolume和rightVolume表示左右音量,priority表示优先级,loop表示循环次数,rate表示速率;而停止则可以使用 pause(int streamID) 方法,这里的streamID和soundID均在构造SoundPool类的第一个参数中指明了总数量,而id从0开始。
sdk21之后:
麻烦很多,在代码中体现。
public class MainActivity extends Activity {
private Button mButtonSoundP
private SoundPool mP
private int voiceID;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButtonSoundPool = (Button) findViewById(R.id.button_sound_pool);
mButtonSoundPool.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mPool.play(voiceID,1,1,0,-1,1);
voiceID = initSoundPool();
private int initSoundPool(){
* 21版本后,SoundPool的创建发生很大改变
//判断sdk版本,如果版本超过21,调用第一种
if(Build.VERSION.SDK_INT&=21){
SoundPool.Builder builder = new SoundPool.Builder();
builder.setMaxStreams(2);//传入音频数量
//AudioAttributes是一个封装音频各种属性的方法
AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);//设置音频流的合适的属性
builder.setAudioAttributes(attrBuilder.build());//加载一个AudioAttributes
mPool = builder.build();
mPool = new SoundPool(2,AudioManager.STREAM_MUSIC,0);
//load的返回值是一个int类的值:音频的id,在SoundPool的play()方法中加入这个id就能播放这个音频
return mPool.load(getApplicationContext(),R.raw.outgoing,1);
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'& 开源中国(OSChina.NET) |
开源中国社区(OSChina.net)是工信部
指定的官方社区

我要回帖

更多关于 soundpool的用法 的文章

 

随机推荐