Android中SoundPool和MediaPlayer优缺点
缺点:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。在快速连续播放声音(连续猛点按钮)时,会出现1~3秒左右的延迟;当然此问题可以使用MediaPlayer.seekTo()这个方法解决。
优点:支持很大的音乐文件播放,而且不会同SoundPool一样需要加载准备一段时间,MediaPlayer能及时播放音乐。MediaPlayer可以播放多种格式的声音文件,例如MP3,AAC,WAV,OGG,MIDI等。MediaPlayer会在framework层创建对应的音频解码器。
缺点:最大只能申请1M的内存空间,意味着用户只能使用一些很短的声音片段,而不能用它来播放歌曲或游戏背景音乐。SoundPool提供了Pause和stop方法,但建议最好不要轻易使用这些方法,因为使用它们会导致程序莫名其妙的终止。使用SoundPool播放音频格式建议使用OGG格式。
优点:
支持多个音乐文件同时播放。
在Android游戏开发中,游戏背景音乐使用MediaPlayer肯定比使用SoundPool要合适;而游戏音效的播放采用SoundPool则更好。
private SeekBar tv_seekBar; private MediaPlayer mediaPlayer; private MyThread myThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_seekBar = (SeekBar) findViewById(R.id.tv_seekBar); myThread = new MyThread(); /** * 给SeekBar 滑动事件:事件监听对象传递进去进行事件监听 */ tv_seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int i, boolean b) { //该方法拖动进度条开始拖动的时候调用 } @Override public void onStartTrackingTouch(SeekBar seekBar) { //该方法拖动进度条停止拖动的时候调用 } @Override public void onStopTrackingTouch(SeekBar seekBar) { //该方法拖动进度条进度改变的时候调用 if (mediaPlayer!=null){ mediaPlayer.seekTo(tv_seekBar.getProgress()); } } }); } public void playOrPause(View view){ //第一步 得到mediaPlayer final ImageButton imageButton=(ImageButton)view; if(mediaPlayer==null){ //这是读取raw下面的文件 //mediaPlayer = MediaPlayer.create(this, R.raw.music); mediaPlayer=new MediaPlayer(); try { //读取内存卡里面的 /* mediaPlayer.setDataSource(this, Uri.parse("file://mnt/sdcard/music/youai.mp3")); mediaPlayer.prepare();*///需要调整 //读取网络上的 mediaPlayer.setDataSource(this,Uri.parse("http://193.168.5.103/youai.mp3")); mediaPlayer.prepareAsync(); } catch (IOException e) { e.printStackTrace(); } /** * 注册一个回调函数,在视频预处理完成后调用。在视频预处理完成后被调用。 * 此时视频的宽度、高度、宽高比信息已经获取到,此时可调用seekTo让视频从指定位置开始播放。 */ mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { private int duration; @Override public void onPrepared(MediaPlayer mediaPlayer) { mediaPlayer.start(); imageButton.setImageResource(android.R.drawable.ic_media_pause); //获取时间的长度 duration = mediaPlayer.getDuration(); //seekBar 设置为最大的长度 tv_seekBar.setMax(duration); myThread.start(); } }); /** * 注册一个回调函数,视频播放完成后调用。 */ mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { if(myThread!=null){//如果播放完了 就给tv_seekBar赋值为0 tv_seekBar.setProgress(0); mediaPlayer.start(); myThread=null; myThread=new MyThread(); myThread.start(); } } }); }else if (mediaPlayer.isPlaying()){ mediaPlayer.pause();//pause 停止 //把图标改为播放图标 imageButton.setImageResource(android.R.drawable.ic_media_play); }else{ mediaPlayer.start();//播放 //把图标改为停止图标 imageButton.setImageResource(android.R.drawable.ic_media_pause); } } class MyThread extends Thread{ @Override public void run() { super.run(); if(tv_seekBar.getProgress()<tv_seekBar.getMax()){ //获取当前的播放位置 int currentPosition =mediaPlayer.getCurrentPosition(); tv_seekBar.setProgress(currentPosition); } } }
布局文件
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <SeekBar android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:id="@+id/tv_seekBar" /> </LinearLayout> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@android:drawable/ic_media_play" android:onClick="playOrPause"/>
<!-- 内存卡读取的权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 网络读取的权限 --> <uses-permission android:name="android.permission.INTERNET" />