хорошо .. это не совсем список воспроизведения, но идея похожа. Я делаю аудиокнигу. И аудиоданные огромны (могут достигать 90 МБ на книгу), поэтому я не хочу загружать все это в память, потому что я знаю об ограничениях памяти, которые имеют эти устройства.
Так что вместо этого я подумал о получении пакета предложений (да, аудиоданные разбиты на предложения и сохранены в локальной базе данных sqlite в виде BLOB-объектов), скажем, 10 или 20, и поместим их в байтовый массив, сохранив каждый из этих 10 или 20-байтовых массивов во временный файл (каждый за раз, как описано здесь для одного массива байтов Android - Воспроизведение mp3 из байта [] ), а затем передайте этот файл MediaPlayer .
Проблема в том, что мне нужно дождаться окончания одного предложения, чтобы начать следующее, чтобы я не перекрывал звуки. Для этого я сделал класс, который содержит MeadiaReader для реализации OnCompletionListener. Поэтому, когда предложение заканчивается, вызывается метод onCompletion. Этот метод запускает другую строку, которая, в свою очередь, вызывает onCopletion в конце и так далее.
В конце концов, это работает, но становится рекурсивным, и мне не нравится, как все это закончилось. Любые идеи о том, как я мог бы лучше реализовать такую функцию в приложении?
--------------------------------------- РЕДАКТИРОВАТЬ ------- -------------------------------
Ну, вот код для пояснения. Я только что получил это NullPointerException, которое вернуло эту трассировку стека:
06-22 12:16:09.152: ERROR/AndroidRuntime(1163): java.lang.NullPointerException
06-22 12:16:09.152: ERROR/AndroidRuntime(1163): at com.spiral.android.IslamicAudioBook.SentencesReader.onCompletion(SentencesReader.java:163)
06-22 12:16:09.152: ERROR/AndroidRuntime(1163): at com.spiral.android.IslamicAudioBook.SentencesReader.playMp3(SentencesReader.java:123)
06-22 12:16:09.152: ERROR/AndroidRuntime(1163): at com.spiral.android.IslamicAudioBook.SentencesReader.onCompletion(SentencesReader.java:163)
06-22 12:16:09.152: ERROR/AndroidRuntime(1163): at com.spiral.android.IslamicAudioBook.SentencesReader.playMp3(SentencesReader.java:123)
.... (продолжает идти так еще 10 строк или около того).
Само исключение легко понять, и оно просто указало на то, что вызов функции происходит рекурсивно. Метод playMp3 очень похож на метод из ссылки, которую я передал выше, а метод onCompletion выглядит примерно так:
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
if(batchSize*batchIndex + sentenceIndex > totalNumberOfSentences){
return;
}
if(batchOfSounds == null){
return;
}
if(sentenceIndex == this.batchSize - 1){
Log.d(TAG,"All sentences from batch read, getting next batch");
this.batchOfSounds = this.getBatchOfSoundsFromDatabase(batchIndex);
}else{
Log.d(TAG,"Playing sentence index: "+sentenceIndex);
}
this.playMp3(batchOfSounds[sentenceIndex],0);
}
Как вы можете легко заметить, исключение возникает только потому, что я тупо проверяю batchOfSounds (который является байтом [] []) на нулевое значение, прежде чем метод getBatchOfSoundsFromDatabase возвращает новую ссылку на него, так что не стоит об этом Я исправлю это.
Но тогда эти 2 метода вызывают друг друга, и вещь явно идет рекурсивно, верно? и я полагаю, что это совсем не хорошо .. верно? или это приемлемо, если я просто не создаю новые ссылки в обоих методах? Если еще немного расширить этот вопрос, то когда допустимо использовать рекурсивный метод? если подумать об этом сейчас, я считаю, что если не создаются новые переменные экземпляра, это может быть приемлемым. Я прав?