如果程序中需要播放密集、急促而又短暂的音效,这个时候你是选择Mediaplayer还是SoundPool呢?看一下对比就会明白。
使用Mediaplayer的缺点:
1)延时时间较长,且资源占用率高。
2)不支持多个音频同时播放。
使用SoundPool的优点:
1:SoundPool使用音效池的概念来管理多个短促的音效
2:CPU资源占用量低和反应延迟小
3:支持自行设置声音的品质、音量、播放比率
SoundPool(int maxStreams, int streamType, int srcQuality):第一个参数指定支持多少个声音;第二个参数指定声音类型:第三个参数指定声音品质。
SoundPool 提供了如下 4 个 load 方法:
int load(Context context, int resld, int priority) // 从resld所对应的资源加载声音。
int load(FileDescriptor fd, long offset, long length, int priority ) // 加载fd所对应的文件的offset开始,长度为length的声音。
int load(AssetFileDescriptor afd, int priority) // 从afd所对应的文件中加载声音。
int load(String path, int priority ) // 从path对应的文件去加载声音。
上面4个方法中都有一个priority参数,该参数目前还没有任何作用,Android建议将该参数设为1,保持和未来的兼容性。
上面4个方法加载声音之后,都会返回该声音的的ID,以后程序就可以通过该声音的ID来播放指定声音。
使用SoundPool播放声音的步骤归纳如下:
1)调用 SoundPool 的构造器创建 SoundPool 的对象。
2)调用 SoundPool 对象的 load() 方法从指定资源、文件中加载声音。最好使用 HashMap< Integer,Integer> 来管理所加载的声音。
3)调用 SoundPool 的 play 方法播放声音。
看下面的Demo程序如何使SoundPool来播放音效。
使用SoundPool时要注意的问题:
1. 音频文件不能太大,否则会造成AudioCache的Heap size overflow
2. 一定要收到onLoadComplete回调之后再play。
3. 要在程序的onDestroy里调用sndPool.release(),否则的话会第二次打开这个程序,不出声音。
4. SoundPool.OnLoadCompleteListener.onLoadComplete(SoundPool soundPool, int sampleId, int status) 的第二个参数sampleId 和 SoundPool.load 返回的参数是同一个东西。
使用Mediaplayer的缺点:
1)延时时间较长,且资源占用率高。
2)不支持多个音频同时播放。
使用SoundPool的优点:
1:SoundPool使用音效池的概念来管理多个短促的音效
2:CPU资源占用量低和反应延迟小
3:支持自行设置声音的品质、音量、播放比率
SoundPool(int maxStreams, int streamType, int srcQuality):第一个参数指定支持多少个声音;第二个参数指定声音类型:第三个参数指定声音品质。
SoundPool 提供了如下 4 个 load 方法:
int load(Context context, int resld, int priority) // 从resld所对应的资源加载声音。
int load(FileDescriptor fd, long offset, long length, int priority ) // 加载fd所对应的文件的offset开始,长度为length的声音。
int load(AssetFileDescriptor afd, int priority) // 从afd所对应的文件中加载声音。
int load(String path, int priority ) // 从path对应的文件去加载声音。
上面4个方法中都有一个priority参数,该参数目前还没有任何作用,Android建议将该参数设为1,保持和未来的兼容性。
上面4个方法加载声音之后,都会返回该声音的的ID,以后程序就可以通过该声音的ID来播放指定声音。
使用SoundPool播放声音的步骤归纳如下:
1)调用 SoundPool 的构造器创建 SoundPool 的对象。
2)调用 SoundPool 对象的 load() 方法从指定资源、文件中加载声音。最好使用 HashMap< Integer,Integer> 来管理所加载的声音。
3)调用 SoundPool 的 play 方法播放声音。
看下面的Demo程序如何使SoundPool来播放音效。
package com.example.isphonenumber;
import java.util.HashMap;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
private Button mButton1 ;
private Button mButton2 ;
SoundPool soundPool;
HashMap<Integer,Integer> musicId=new HashMap<Integer,Integer>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化soundPool,第一个参数音频流的个数,第二个参数是音频流的质量
soundPool=new SoundPool(10, AudioManager.STREAM_SYSTEM,5);
// 通过 load 方法加载指定音频流,并将返回的音频 ID 放入 musicId 中
musicId.put(1, soundPool.load(this, R.raw.camera_click, 1));
musicId.put(2, soundPool.load(this, R.raw.accept_reminder,1));
mButton1 = (Button) findViewById(R.id.btok1);
mButton1.setOnClickListener(this);
mButton2 = (Button) findViewById(R.id.btok2);
mButton2.setOnClickListener(this);
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()) {
case R.id.btok1:
soundPool.play(musicId.get(1),15,15, 0, 0, 1f);
break;
case R.id.btok2:
soundPool.play(musicId.get(2),15,15, 0, 0, 1f);
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//M:lyj 释放音源资源
soundPool.release();
}
}
别忘了把你的音源资源放在res/raw/这个路径下
注意:SoundPool虽然可以一次性加载多个声音,但由于内存限制,因此应该避免使用 SoundPool 来播放歌曲或者做游戏背景音乐,只有那些短促,密集的声音才考虑使用SoundPool进行播放。
虽然SoundPool比MediaPlayer的效果好,但也不是绝对不存在延迟问题,尤其在那些性能不太好的手机中,SoundPool 的延迟问题会更严重。使用SoundPool时要注意的问题:
1. 音频文件不能太大,否则会造成AudioCache的Heap size overflow
2. 一定要收到onLoadComplete回调之后再play。
3. 要在程序的onDestroy里调用sndPool.release(),否则的话会第二次打开这个程序,不出声音。
4. SoundPool.OnLoadCompleteListener.onLoadComplete(SoundPool soundPool, int sampleId, int status) 的第二个参数sampleId 和 SoundPool.load 返回的参数是同一个东西。