Нужно сделать какой-то плейлист для андроид приложения - PullRequest
0 голосов
/ 22 июня 2011

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

0 голосов
/ 22 июня 2011

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

...