3. SoundPool的效率问题。其实SoundPool的效率在这些播放类中算是很好的了,这可能会影响用户体验。也许这不能管SoundPool本身,因为到了性能比较好的Droid中这个延迟就可以让人接受了。
4. 有的文件虽然很小,但是解码出来为16位的PCM可能会超过1M的空间这时只能播放很短的部分声音。文件超过1M的就播不了了。
下面直接上代码
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@+id/StartButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始播放" /> <Button android:id="@+id/PauseButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="暂停播放" /> <Button android:id="@+id/StopButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="停止播放" /> </LinearLayout>源代码
package com.example.testsoundpool; import java.util.HashMap; import android.R.bool; import android.media.AudioManager; import android.media.SoundPool; import android.media.SoundPool.OnLoadCompleteListener; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener{ private SoundPool sp=null;//声明一个SoundPool的引用 private HashMap <Integer,Integer> hm;//声明一个HashMap来存放声音资源 private int currentStreamId;//当前播放的StreamId private Button startPlayButton;//播放按钮 private Button PausePlayButton;//暂停按钮 private Button stopPlayButton;//停止播放 private Boolean isFinishedLoad=false;//查看音乐文件是否加载完毕 private Boolean isPausePlay=false;//是否暂停播放 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //按钮点击响应函数 startPlayButton=(Button)findViewById(R.id.StartButton); PausePlayButton=(Button)findViewById(R.id.PauseButton); stopPlayButton=(Button)findViewById(R.id.StopButton); startPlayButton.setOnClickListener(this); PausePlayButton.setOnClickListener(this); stopPlayButton.setOnClickListener(this); //初始化SoundPool initSoundPool(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } //按钮响应函数 @Override public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()){ case R.id.StartButton: playSound(1,0);//播放dudu,dudu文件被解码为16位的PCM数据后超过了SoundPool的1M缓冲区了,循环不了,而且不能播完整个歌曲 //playSound(2,-1);//循环播放musictest break; case R.id.PauseButton: isPausePlay=true; sp.pause(currentStreamId); break; case R.id.StopButton: isPausePlay=false; sp.stop(currentStreamId); break; default: System.out.println("switch default"); break; } } public void initSoundPool(){ System.out.println("+initSoundPool+"); sp=new SoundPool(4,AudioManager.STREAM_MUSIC,0);//创建SoundPool对象 sp.setOnLoadCompleteListener(new OnLoadCompleteListener() { @Override public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { // TODO Auto-generated method stub isFinishedLoad=true; System.out.println("setOnLoadCompleteListener"); } }); hm=new HashMap<Integer,Integer>();//创建HashMap对象 hm.put(1, sp.load(this, R.raw.dudu, 0));//加载dudu声音文件并设置为1号文件放入hm hm.put(2, sp.load(this, R.raw.musictest, 0));//加载musictest声音文件并设置为2号文件放入hm System.out.println("-initSoundPool-"); } //sound hm中的第几个歌曲 //loop 是否循环 0不循环 -1循环 public void playSound(int sound,int loop){ String log; if(!isPausePlay){ AudioManager am=(AudioManager)this.getSystemService(AUDIO_SERVICE); float currentStreamVolume=am.getStreamVolume(AudioManager.STREAM_MUSIC); float maxStreamVolume=am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); float setVolume=(float)currentStreamVolume/maxStreamVolume; if(isFinishedLoad) currentStreamId=sp.play(hm.get(sound), setVolume, setVolume, 1, loop, 1.0f); log="playSound currentStreamId:"+String.valueOf(currentStreamId); System.out.println(log); } else{ isPausePlay=false; sp.resume(currentStreamId); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); sp.unload(currentStreamId); sp.release(); } }