Нужно сделать какой-то плейлист для андроид приложения

Ну.. это не совсем список воспроизведения, но идея похожа. Я делаю аудиокнигу. И аудиоданные огромны (может достигать 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 метода вызывают друг друга, и дело явно идет рекурсивно, верно? и я полагаю, что это совсем не хорошо.. верно? или это приемлемо, если я просто не создаю новые ссылки в обоих методах? Если еще немного расширить этот вопрос, то когда приемлем рекурсивный метод? если подумать об этом сейчас, я считаю, что если не создаются новые переменные экземпляра, это может быть приемлемым. Я прав?

1 ответ

Решение

То, как вы это делаете, звучит разумно, хотя я не уверен на 100%, что знаю, что вы имеете в виду без небольшого кода или псевдокода. Тем не менее, если вам не нравится, как он структурирован, как насчет этого: у вас может быть класс, который оборачивает медиаплеер, который поддерживает очередь материала для воспроизведения. Он по-прежнему слушает onCompletion, просто извлекает следующий элемент из очереди и воспроизводит его. Вы можете сохранить отдельный класс "загрузчик", который заполняет очередь onCompletion. Таким образом, вы можете разделить проблемы, оставляя игрока обеспокоенным игрой и классом загрузчика только с загрузкой.

Другие вопросы по тегам