Re: Урок 80. Handler. Немного теории. Наглядный пример испо
Добавлено: 11 авг 2013, 03:29
да, ты прав, с этой штукой нужно или INVISIBLE или GONE
Добро пожаловать на форум сайта
http://forum.startandroid.ru/
Это глубочайшее заблуждение и скажите, неужели действительно думаете, что гениальность многопоточности java была бы возможна, если бы сие было правдой?MeTeOpA писал(а):В Java насколько я знаю поток можно создать 2мя способами .
Код: Выделить всё
ExecutorService service = Executors.newFixedThreadPool(4);
for(int i = 0; i < 10; i++) {
service.submit(
//Some operetions here...
);
}
Код: Выделить всё
Iterator<E> iter = collection.iterator();
Код: Выделить всё
iter.hasNext();
iter.next();
iter.remove();
начнем с того, что как минимум с помощью метода Call (inerface Callable<T>) можно реализовать вычисления в отдельном классе(вынести туда Lock -и и Semaphor - ы). Но как потом запустить? В ручную создавать потоки, далее объекты класса и т.д.? ExecutorService - дает очень мощный и безопасный способ запуска(к слову он и является сервисом запуска потоков) и предоставляет кучу очень мощных средств контроля в том числе отложенных вычислений и т.д. Хотя судя по тому, что я написал - это врятли что -то объясняет) но простите я не умею объяснять... могу лишь порекомендовать ознакомиться поглубже с книжкой Java Concurrency in Practice, понять все преимущества, а иногда и то, что без подобных инструментов не возможно работать можно понять только используя на реальных задачах.no-- писал(а):Ну на сколько я понял, прочитав вскользь ExecutorService, это просто пул потоков. Т.е. это много вот таких вот "Thread.start". Сам Thread.start, запускается в одном, новом потоке.
Thread().start создает объект класса Thread и запускает его, класс ExecutorService содержится в java.util.concurrent.ExecutorService, т.е. это другой класс и он не создает поток а лишь содержит инструменты эффективной работы с ним. Для того, чтобы его использовать Необходимо реализовать метод call() интерфейса callable, преимуществ очень много, но очевидны они там где много потоков и много вычислений, там где нужны высокоуровневые и надежные средства обработки... Новичку в java для начала я бы рекомендовал понять что такое deadlock и как с ним бороться... научиться использовать synchronize и только потом учиться обходиться без него и работать потокобезопастно... хотя по сути правильная архитектура данных может заменить все... но в реальной жизни -это практически не возможноnubodroid писал(а):Всем доброй ночи, прошу прощения... чем отличается Thread.start() от ExecutorService.executor(Runnable);
Просто... решил попробовать сделать живые обои... нарыл кучу статей и... в рез-те вернулся на форум. Просто во всех статьях каждый делает по своему... Основной принцип понятен, но из-за вот таких ExecutorService(пример из книги Эд Бурнет "Привет, Андроид! Разработка мобильных приложений")... Просто я в Java новичок совсем... Параллельно читаю.
Всем заранее спасибо
altwin писал(а):Thread().start создает объект класса Thread и запускает его, класс ExecutorService содержится в java.util.concurrent.ExecutorService, т.е. это другой класс и он не создает поток а лишь содержит инструменты эффективной работы с ним. Для того, чтобы его использовать Необходимо реализовать метод call() интерфейса callable, преимуществ очень много, но очевидны они там где много потоков и много вычислений, там где нужны высокоуровневые и надежные средства обработки... Новичку в java для начала я бы рекомендовал понять что такое deadlock и как с ним бороться... научиться использовать synchronize и только потом учиться обходиться без него и работать потокобезопастно... хотя по сути правильная архитектура данных может заменить все... но в реальной жизни -это практически не возможноnubodroid писал(а):Всем доброй ночи, прошу прощения... чем отличается Thread.start() от ExecutorService.executor(Runnable);
Просто... решил попробовать сделать живые обои... нарыл кучу статей и... в рез-те вернулся на форум. Просто во всех статьях каждый делает по своему... Основной принцип понятен, но из-за вот таких ExecutorService(пример из книги Эд Бурнет "Привет, Андроид! Разработка мобильных приложений")... Просто я в Java новичок совсем... Параллельно читаю.
Всем заранее спасибо
Хендлер не имеет отношения к runnable. Вы можете запускать, что угодно, но если потоков более одного lock/syncronize перед помещением в хендлер- ваша проблема. Хендлер по сути просто формирует очередь сообщений для главного потока и иметь более одного бессмысленно. Вам нужно вручную синхронизировать потоки либо, что удобней использовать lock, опять же есть различные executors для запуска потоков, вариантов куча -это же java.qualitat1ve писал(а):Я так понимаю для 1 потока нельзя создать несколько хендлеров? Как быть если мне надо запустить 2 фоновых потока, каждый из которых должен иметь доступ к компонентам UI?
AsyncTask в помощьbayah писал(а):Доброй ночи, товарищи.
Подскажите, пожалуйста.
Я хочу сделать 2 потока(ну основной UI и еще один ......
.....отсылать сообщения из UI-потока в поток проигрывателя.
Или как-то иначе надо?)
Handler привязан к тому потоку, в котором он создается. В данном уроке Handler создается в UI-потоке (в onCreate() Activity), поэтому он к нему и "привязан".bayah писал(а): В уроке реализована возможность из созданного потока отослать сообщение в основной UI-поток. А как сделать, чтобы из UI-потока отправить сообщение в созданный поток?
Leeroy писал(а):AsyncTask в помощьbayah писал(а):Доброй ночи, товарищи.
Подскажите, пожалуйста.
Я хочу сделать 2 потока(ну основной UI и еще один ......
.....отсылать сообщения из UI-потока в поток проигрывателя.
Или как-то иначе надо?)
Код: Выделить всё
public class MyThread extends Thread {
public Handler h_in;
public MyThread(Runnable runnable){
super(runnable);
h_in = new Handler() {
public void handleMessage(android.os.Message msg) {
h.sendEmptyMessage(msg.what);
}
};
}
}
Код: Выделить всё
h = new Handler() {
public void handleMessage(android.os.Message msg) {
// обновляем TextView
tvInfo.setText("Пришло сообщение: " + msg.what);
}
Код: Выделить всё
t = new MyThread(new Runnable() {
public void run() {
int a = 10;
}
});
Поток в свою очередь отсылает сообщение Handler'у основного UI-потока и тот уже отображает его.
t.h_in.sendEmptyMessage(11);
Не совсемbayah писал(а):
Так вот. Зачем нам Runnable и правильно ли я все понял или какую-то чушь нагородил?)
Ну тем не менее я уже посылал сообщение и оно обрабатывалось и возвращалось. Исключений не было.Viewer писал(а):bayah писал(а): И еще - вот этот код int a = 10;, который у вас новом потоке, отработает за тысячные доли секунды, а если вы будете посылать сообщения в отработавший поток, то скорее всего получите исключение. Вам нужны более долгоживущие потоки ))
Потому и не было исключений, что сообщения отправляются в UI-потоке и принимаются в UI-потоке , см. первую часть моего поста.bayah писал(а): Ну тем не менее я уже посылал сообщение и оно обрабатывалось и возвращалось. Исключений не было.
Service... другие варианты для плеера мне кажутся ненадежными.bayah писал(а):Доброй ночи, товарищи.
Подскажите, пожалуйста.
Я хочу сделать 2 потока(ну основной UI и еще один поток). Эти потоки должны мочь "общаться" друг с другом, то есть посылать друг другу сообщения.
В уроке реализована возможность из созданного потока отослать сообщение в основной UI-поток. А как сделать, чтобы из UI-потока отправить сообщение в созданный поток?
Вообще это мне нужно, чтобы сделать плеер, проигрывание музыки в котором должно быть в отдельном потоке. Таким образом, чтобы управлять проигрыванием нужно будет отсылать сообщения из UI-потока в поток проигрывателя.
Или как-то иначе надо?)
Viewer писал(а):Потому и не было исключений, что сообщения отправляются в UI-потоке и принимаются в UI-потоке , см. первую часть моего поста.bayah писал(а): Ну тем не менее я уже посылал сообщение и оно обрабатывалось и возвращалось. Исключений не было.
А вообще Handler не применим к потоку в том виде в котором вы его написали. Handler применяется только к тем потокам у которых есть Looper (петля) т.е. к потокам, которые не завершаются отработав какой-то код, а переходят в режим приема сообщений (они еще называются "Looper Thread", UI-поток именно таковым и является). Т.е. Looper это фактически цикл обработки сообщений, который организует обработку сообщений в порядке очереди, без него отправлять сообщения просто некуда.
[syntax=java] class MyThread extends Thread {
public Handler h;
public void run() {
Looper.prepare();
h = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0) {
Log.d(TAG, "handleMessage_quit");
Looper.myLooper().quit();
} else {
Log.d(TAG, "handleMessage-"+msg.what);
}
}
};
Looper.loop();
Log.d(TAG, "QUIT");
}
}[/syntax]
Запускаем поток как обычно
[syntax=java]MyThread t = new MyThread();
t.start();[/syntax]
Отправляем сообщения потоку
[syntax=java]t.h.sendEmptyMessage(1);
//Сообщение для завершения потока
t.h.sendEmptyMessage(0);[/syntax]
ЗЫ Кстати, сообщения отправленные отработавшему, неактивному потоку не вызывают исключения, но и не выполняются, т.е. отправляются в никуда и метод sendEmptyMessage() возвращает false в этом случае.
А почему именно Service?klblk писал(а): Service... другие варианты для плеера мне кажутся ненадежными.
Интуитивно как-то =) Длительная задача, не зависит от ui и не убивается "случайно" Андроидом. Service в режиме iddqd, wakelock и нотификашка (как бонус).bayah писал(а):А почему именно Service?klblk писал(а): Service... другие варианты для плеера мне кажутся ненадежными.