2014-08-26 4 views
0

Из моего основного потока я запускаю AsyncTask, который будет проходить через список изображений и для каждого изображения, он будет выполнять некоторую обработку на нем. Итак, в основном, есть цикл for и внутри него, вызывается другая AsyncTask. Я использую экземпляр класса, который содержит логическое значение для проверки, выполняется ли каждое изображение с его обработкой, его называют dummyStructure.Android Threading (AsyncTasks) действует немного странно

Код основного потока:

new BatchProcessor().execute() 

doInBackground из BatchProcessor:

protected Void doInBackground(Void... params){ 

while(dummyStructure.isWorking()) 
{ 
//Try loop 
    thread.sleep(1000); 
} 
    dummyStructure.setIsWorking(true); //basically sets the flag to true 
for(String s: pictureList) 
{ 
    RunTheProcessingLoop().execute(); 
} 

Проблема: Я пытался отладки, и вот, что проблема имо, если я удалить линии за пределами цикла while dummyStrucutre.setIsWorking(true), тогда есть несколько асинхронных вызовов, которые еще до того, как они заканчиваются, и в основном все становится испорченным. Однако, если я не удаляю эту строку, то BatchProcessor AsyncTask попадает в цикл while, а поскольку RunTheProcessingLoop AsyncTask никогда не выполняется за пределами своего onPreExecute() (отлаженный, чтобы знать это, я использовал Log.e() в каждом методе этой asyncTask).

Определенно, я что-то упускаю, любая помощь? Большое спасибо! :)

+0

Зачем вы вызываете задачу async из другой задачи async? Async в Android - это в основном запланированные задания, которые работают в основной структуре приложения. Это часто позволяет сэкономить ресурсы процессора, убедившись, что все эти виды заданий выполняются из одного механизма планировщика. Когда вы вызываете execute, он добавляет его в очередь расписания, нет никакой логики, чтобы вы не добавляли задание более одного раза в планировщик. – bond

+0

Я понимаю, о чем вы говорите. Но тогда как я могу назвать основной AsyncTask -> 'RunTheProcessingLoop()' из основного потока, а также дождаться его завершения? Я считаю, что мне нужно будет назвать это несколько раз в соответствии с требованиями. : \ –

+0

Не запускайте вещи из основного потока. Ожидание завершения AsyncTask противоречит дизайну AsyncTask в целом. Первое правило AsyncTasks заключается в том, что вся логика, выполняемая AsyncTasks, должна быть доступна из любого места напрямую, а не через ограниченный интерфейс AsyncTask. Это позволяет вам напрямую вызывать различные блоки задач из других задач. Опубликуйте как можно больше кода для этого класса, который вы можете использовать в pastebin, и я исправлю это. – bond

ответ

1

То, с чем вы сталкиваетесь, - это асинхронность, которая складывается из-за того, что вы начинаете один с другого и не выходите из первого. Это связано с тем, что asynctasks обрабатываются по отдельности одним потоком по умолчанию. Если вы хотите использовать несколько потоков параллельно, вам нужно будет использовать собственный исполнитель потока. Дополнительную информацию см. В документации AsyncTask.

+0

Ты супер потрясающий! Большое спасибо @LarrySchiefer, это очень помогло мне. Я знаю, что это не может быть связано с «лучшей практикой программирования на Java/Android», но хорошая новость: IT WORKS! –

+0

Рад, что вы нашли это полезным! Удачи! –

0

Таким образом, после 2 дней размещения на этот вопрос и узнать больше о том, что отправил людей, я понял это:

Мой главный поток, называемый для AsyncTask, и я хотел ждать, что AsyncTask закончить. Таким образом, я использовал логический флаг, который AsyncTask устанавливает в false, когда это будет сделано, и я могу поставить в очередь другую задачу. Вот код:

class mExecutor implements Executor { 
      public void execute(Runnable r) { 
      new Thread(r).start(); 

     }} 

Теперь все, что вам нужно сделать, это, независимо от задачи/метод/и т.д. вы хотите запустить Асинхронный, просто создать поток и толкать его в этом классе, например:

Thread t = new Thread(new Runnable() { 
         public void run() { 
          new someshit().execute(); 
           } 
          }); 
new mExecutor().execute(t); 

и Tada! Теперь они оба не будут поставлены в очередь/синхронизированы, но будут работать параллельно.

Если я ошибаюсь, пожалуйста, исправьте меня! Благодаря! :)

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