2014-10-30 4 views
0

Я читаю строки текста из входного потока (в настоящее время текстового файла, в конечном счете, через блютус)Android Наблюдаемые/AsyncTask ждать до завершения цикла перед выполнением

Линия заворачивает в bufferItem и добавляет к буфер (ArrayList), который запускает Наблюдаемое &

setChanged(); 
notifyObservers(item); 

метод обновления на пожарах наблюдателей от с AsyncTask для каждого элемента буфера.

Поскольку мой поток ввода будет по существу «бесконечным», я хочу, чтобы все это происходило одновременно (т.е. данные обрабатываются, а новые данные также поступают в реальном времени), но я обнаружил, что asyncTasks не начинайте, пока весь файл не будет прочитан.

Чтение битого файла ниже:

while (((inputLine = bufferedReader.readLine()) != null)) { 

    if (inputLine.substring(0,1).equals("$")){ 
    bufferItem bi = new bufferItem(); 
    bi.addItem(inputLine); 
     for (int i = 1; i < repeatRate; i++) { 
      bi.addItem(bufferedReader.readLine()); 
     } 
    // adding to buffer triggers the observer 
    buffer.addItem(bi); 
    } 
} 

Наблюдаемый весь процесс/наблюдатель работает, но ни один из последующих процессов не удар, пока после того, как весь входной файл был прочитан.

Я мониторинг его с помощью линий, аналогичные:

System.out.println("Item added to buffer"); 

С Println в точке, где элемент добавляется в буфер, а другой в одном из последующих процессов внутри AsyncTask

Поэтому сначала я получаю все строки «Item added to buffer», за которыми следуют строки журнала процессов в нисходящем потоке, когда я ожидаю, что они будут перемешаны.

Так что вопрос (я думаю) - почему он дожидался завершения цикла, прежде чем действовать над инструкциями notifyObservers()?

+0

Почему так голосуют? – Mitch

ответ

0

Похоже, что это связано с тем, как Honeycomb (и позже) обрабатывает AsyncTask - путем помещения AsyncTasks в тот же поток и не имеет отношения к шаблону Observer, как я думал раньше.

Чтобы заставить его работать, я переехал код для чтения файлов в отдельный AsyncTask и назвал его так:

task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 

Это позволяет AsyncTasks, которые обрабатывают данные файла, чтобы начать немедленно.

Если они, в свою очередь, называют в «стандартной» способ

new Task(param1, param2).execute(); 

, то они будут работать в определенной последовательности.

Они также могут быть вызваны таким образом:

new Task(param1, param2).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 

в этом случае они также будут работать параллельно, но не в том порядке, в котором данные отрываясь файл читается. Это важно, если вам нужно упаковать данные файла, используя тот же порядок, что и в файле.

Эта статья была ключом:

http://www.techrepublic.com/blog/software-engineer/android-asynctask-behavior-changes-you-should-know/

Кроме того, Android док - прокрутите вниз до порядка выполнения

http://developer.android.com/reference/android/os/AsyncTask.html

1

Кажется, что последовательность пакетов данных/строк имеет значение:

  1. Поток приемника для чтения ввода в кусках, добавьте их в очередь буфера ввода.

  2. Процессорный поток, чтобы просмотреть() входную очередь, обрабатывать элементы и поместить их в очередь выходных буферов. Если входная очередь пуста, этот поток ожидает, что приемник помещает что-то в очередь и уведомляет об этом.

  3. И наконец, поток диспетчера для отправки/записи/сохранения/etc обработанных элементов из очереди выходных буферов. Если очередь вывода пуста, этот поток ожидает, что процессор поместит что-то в очередь и уведомит об этом.

Вам нужно будет иметь верхний предел в буферных очередях, поэтому они блокируются при заполнении, иначе вы можете закончиться из ОЗУ. Также убедитесь, что поток не заблокирован из-за ошибки нити.

Смежные вопросы