我无法弄清楚为什么MediaPlayer
有时会播放,有时不会播放同一个文件。有大约目录中的2000个音频文件。它可能发生在任何一个。通过下一个应用程序运行,它可能是一些受影响的其他文件。我对此没有任何解释。
以下是代码:
private void play(List<Integer> lineIndices, final MediaPlayer.OnCompletionListener completionListener) {
Log.d("ENTER lineIndices.size()=", lineIndices.size());
File sdcard = (RUNS_ON_EMULATOR) ? Environment.getExternalStorageDirectory() : new File("/storage/sdcard1");
final List<MediaPlayer> players = new ArrayList<>();
for (Integer index : lineIndices) {
Uri uri = Uri.fromFile(new File(sdcard + DEFAULT_FOLDER + getFileName(index)));
Log.d("File URI=%s", uri.toString());
MediaPlayer player = MediaPlayer.create(context, uri);
players.add(player);
}
for (int i = 0; i < players.size() - 1; i++) {
players.get(i).setNextMediaPlayer(players.get(i + 1));
}
MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
completionListener.onCompletion(mediaPlayer);
for (MediaPlayer player : players) {
player.release();
}
}
};
if (!players.isEmpty()) {
players.get(players.size() - 1).setOnCompletionListener(listener);
Log.d("Before players.get(0).start();");
players.get(0).start();
}
Log.d("EXIT");
}
日志输出显示文件已确定且已调用players.get(0).start()
:
com.android.vocabularytrainer D/VocabularyTrainerModelImpl: [play] ENTER lineIndices.size()=
com.android.vocabularytrainer D/VocabularyTrainerModelImpl: [play] File URI=file:///storage/sdcard1/tmp/english/vocabulary/000010.wav
com.android.vocabularytrainer D/VocabularyTrainerModelImpl: [play] Before players.get(0).start();
com.android.vocabularytrainer D/VocabularyTrainerModelImpl: [play] EXIT
我尝试通过仅使用一个MediaPlayer
实例来解决此问题,而不是使用setNextMediaPlayer
方法并引入方法调用setDataSource(), prepare()
和reset()
。它稍微改善了这种情况,但仍然可能发生不播放文件的情况。然而,事情并不像以前那么频繁。
private void play(final List<Integer> lineIndices, final MediaPlayer.OnCompletionListener completionListener) {
Log.d("ENTER lineIndices.size()=%d", lineIndices.size());
if (!lineIndices.isEmpty()) {
final File sdcard = (RUNS_ON_EMULATOR) ? Environment.getExternalStorageDirectory() : new File("/storage/sdcard1");
final MediaPlayer player = new MediaPlayer();
final Uri uri = Uri.fromFile(new File(sdcard + DEFAULT_FOLDER + getFileName(lineIndices.get(0))));
try {
player.setDataSource(context, uri);
MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() {
private int i = 1;
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
if (i < lineIndices.size()) {
final Uri uri = Uri.fromFile(new File(sdcard + DEFAULT_FOLDER + getFileName(lineIndices.get(i++))));
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(context, uri);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d("%s", uri.toString());
mediaPlayer.start();
}
});
mediaPlayer.prepare();
return;
} catch (IOException e) {
Log.e("Unable to play file", e);
}
}
completionListener.onCompletion(mediaPlayer);
mediaPlayer.release();
}
};
player.setOnCompletionListener(listener);
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d("%s", uri.toString());
player.start();
}
});
player.prepare();
} catch (IOException e) {
Log.e("Unable to play file", e);
}
}
Log.d("EXIT");
}
答案 0 :(得分:0)
根据我的经验,它看起来像内存不足问题。问题随机发生?记忆问题呢。限制应用中的mediaPlayers数量并仔细管理(2或3)。不要过多准备媒体。如果我是正确的 - MediaPlayer.create()将在创建时准备媒体,消耗内存。
<强>已更新强>
我发现MediaPlayer没有参考。这意味着MediaPlayer可以随时进行GC。通常,在GCed时,mediaPlayer将停止播放。 跟踪MediaPlayer并参考。
MediaPlayer mPlayer; // field Variable
...
private void play(final List<Integer> lineIndices, final MediaPlayer.OnCompletionListener completionListener) {
...
mPlayer = new MediaPlayer();
...