2012-04-10 2 views
0

Я читал, что основной поток пользовательского интерфейса в android не должен вызывать сон.UI поток ожидает выполнения других потоков - Не работает

Однако мое приложение должно:

  1. вызова thread1 из основного потока пользовательского интерфейса
  2. вызова thread2 из основного потока пользовательского интерфейса.

Используйте выходные данные (2 изображения) из 2 потоков, добавьте их, а затем отобразите их.

Я использую Thread.sleep(), так что основной поток ждет thread1 и thread2, пока они не будут выполнены. Однако mImageview.setbitmap не работает после того, как я назову его в основном потоке (после сна).

может ли посоветовать мне, как я должен это делать?

ответ

1

Многопоточность в Android должна выполняться асинхронно. Для этой цели вы должны использовать AsyncTask-class.

Для вашего случая вы бы, например, создали taks для загрузки (или обработки) этих двух изображений. Пока процесс выполняется (в другом потоке, вне пользовательского интерфейса), вы можете показать ProgressBar, который показывает пользователю, что ваше приложение занято (это выполняется в пользовательском интерфейсе).

Когда задача завершена, вы получаете результаты (два ваших изображения) из задачи, скрываете индикатор выполнения и показываете все пользователю.

Несмотря на то, что не реагирующий графический интерфейс всегда имеет ощущение, что ваше приложение застыло, если UI-поток заблокирован более чем на 5 секунд (что является временным временем), ваше приложение будет принудительно закрыто как он не «реагирует» (и будет поднят ANR).

+0

Ожидание в обработчике событий встает туда, где «моя плавающая точка сравнивает неудачу» и «как я могу остановить поток?» :( –

+0

Другое дело - если графический интерфейс заблокирован, кнопка «Отменить операцию» не может быть отключена. Это невероятно расстраивает и раздражает пользователей, когда они не могут остановить то, что они начали по ошибке. Сегодня нет никаких оправданий для приложений «Песочные часы» '. –

+0

@MartinJames вы можете отменить «AsyncTask». Это может быть реализовано с помощью кнопки или «назад». –

0

Это не просто Thread.Sleep(). В потоке GUI сделайте все, что вам нужно, чтобы запустить два потока/задачи/независимо, а затем выйдите из обработчика событий.

Не ждите в обработчиках событий GUI! Не в Java, C++, C, Delphi, ничего. Используйте задачу async или обработчик и сигнал к потоку графического интерфейса. Поток 1 сигнализирует, что это сделано, поток 2 сигнализирует, что это сделано. В любом случае проверьте, были ли данные возвращены другим потоком. Если это так, у вас есть оба набора возвращаемых данных, и вы можете их добавить и отобразить.

Не ждите в обработчиках событий GUI.

0

Для этой цели вы можете просто использовать Threads And Handlers. Вот небольшой демо для этого,

Создать Handler в вашем OnCreate, как это,

Drawable d=null;  

Handler handler=new Handler() 
{ 

public void handleMesaage(Message msg) 
{ 
    if(msg.what==0) 
{ 
    imageView.setBackgroundDrawable(d); 
} 

} 

}; 

И теперь называем свою нить, как это,

Thread t=new Thread(new Runnable() 
{ 
@Override 
public void run() { 
    InputStream is = (InputStream) new URL(url).getContent(); 
    d = Drawable.createFromStream(is, "src name"); 
    handler.sendEmptyMessage(0); 
} 
});t.start(); 
0

Я хотел бы предложить используйте ExecutorService. Вот как

  1. Создайте две операции загрузки изображений как Runnable tasks.
  2. Выполните их с помощью ExecutorService.
  3. ExecutorService.awaitTermination(); для основного потока ждать выполнения задач Runnable. Его документация читает

блоков, пока все задачи не будут завершены выполнение после выключения запроса, или тайм-аут происходит, или текущий поток прерывается, зависимости от того, что произойдет раньше.

Это Асинхронный способ сделать это, и я думаю, это должно быть предпочтительнее.

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