我正在使用一种方法来初始化和准备一个MediaPlayer(定义为类变量)。它需要一个String作为参数的歌曲名称,它将DataSource设置为该特定路径。
public void create_and_prepare_song(String x) {
if (mp != null)
mp.release();
mp = new MediaPlayer();
String filePath = Environment.getExternalStorageDirectory().getPath() + "/songsfolder/" + x + ".mp3";
try {
mp.setDataSource(filePath);
} catch (IOException e) {
e.printStackTrace();
}
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
现在,在我的代码中的某处,我使用此方法初始化并准备“1.mp3”。然后,只要这首歌结束,我就使用onCompletionListener,以便播放“2.mp3”,然后播放“3.mp3”。我用:
create_and_prepare_song("1");
i = 2;
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (i <= 3) {
String int_to_String = i + "";
create_and_prepare_song(int_to_String); //1
mp.setOnCompletionListener(this);
mp.start();
i++;
}
}
});
mp.start();
现在,这会导致应用停止工作!但是,如果我只是将方法的主体复制并粘贴到// 1行,那么应用程序可以正常工作,播放第一首,第二首和第三首歌曲。为什么会这样?非常感谢
答案 0 :(得分:2)
请注意,您正在create_and_prepare_song()
内创建一个新玩家,但旧的玩家仍会在侦听器内部被引用。
那是因为全局变量和onCompletion参数具有相同的名称:mp
。
这里有一段有用的代码:
package com.example.simon.mplaylist;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import java.io.IOException;
/**
* Created by Simon on 2014 Jul 20.
*/
public class MainActivity extends Activity {
static int currentSong;
static MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mediaPlayer != null)
return;
currentSong = 1;
create_and_prepare_song(currentSong);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (currentSong++ >= 3) {
mediaPlayer = null;
return;
}
create_and_prepare_song(currentSong);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.start();
}
});
mediaPlayer.start();
}
public void create_and_prepare_song(int songNum) {
if (mediaPlayer != null)
mediaPlayer.release();
mediaPlayer = new MediaPlayer();
String storage = Environment.getExternalStorageDirectory().getPath();
String filePath = storage + "/songsfolder/" + String.valueOf(songNum) + ".mp3";
try {
mediaPlayer.setDataSource(filePath);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意我还将MediaPlayer定义为静态,并且还要检查@ onCreate是否存在。这样,如果重新创建活动(例如屏幕旋转),则可以避免一次播放多首歌曲。
答案 1 :(得分:0)
你真的不应该在create_and_prepare_song()
内开始实际播放。它应该在onPrepared()
内启动,因为从prepare()
调用可能会有一些延迟,并且媒体已准备好播放。