Это связано с тем, что ваш элемент динамически создан, и вы должны делегирование событий обрабатывать событие.
document.addEventListener('click',function(e){
if(e.target && e.target.id== 'brnPrepend'){//do something}
})
jquery упростить:
$(document).on('click','#btnPrepend',function(){//do something})
Вот статья, которую вы можете прочитать о делеции делегирования событий .
Использование Future, описанное в приведенных выше ответах, выполняет задание, но немного менее существенно, как f.get (), блокирует поток до получения результата, что нарушает параллелизм.
Лучшее решение - использовать ListenableFuture от Guava. Пример:
ListenableFuture<Void> future = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1, new NamedThreadFactory).submit(new Callable<Void>()
{
@Override
public Void call() throws Exception
{
someBackgroundTask();
}
});
Futures.addCallback(future, new FutureCallback<Long>()
{
@Override
public void onSuccess(Long result)
{
doSomething();
}
@Override
public void onFailure(Throwable t)
{
}
};
Как насчет этого решения?
Он не использует класс Thread, но он является параллельным и таким образом делает именно то, что вы запрашиваете
ExecutorService pool = Executors.newFixedThreadPool(2); // creates a pool of threads for the Future to draw from
Future<Integer> value = pool.submit(new Callable<Integer>() {
@Override
public Integer call() {return 2;}
});
Now все, что вы делаете, это сказать value.get()
всякий раз, когда вам нужно захватить возвращаемое значение, поток запускается в самый последний момент, когда вы даете value
значение, поэтому вам никогда не придется говорить threadName.start()
.
Что такое Future
, является обещанием для программы, вы обещаете программе, что вы получите ее значение, которое потребуется в ближайшем будущем
Если вы назовете .get()
на нем до того, как это будет сделано, поток, который его вызывает, просто просто дождитесь, пока это будет сделано
С небольшими изменениями в вашем коде вы можете достичь этого более общим способом.
final Handler responseHandler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Result from UIHandlerThread:"+(int)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
HandlerThread handlerThread = new HandlerThread("UIHandlerThread"){
public void run(){
Integer a = 2;
Message msg = new Message();
msg.obj = a;
responseHandler.sendMessage(msg);
System.out.println(a);
}
};
handlerThread.start();
Решение:
Handler
в потоке пользовательского интерфейса , который называется responseHandler
Handler
из Looper
раздела UI Thread. HandlerThread
сообщение post на этом responseHandler
handleMessgae
показывает Toast
со значением, полученным от сообщения. Этот объект сообщения является общим и вы можете отправлять разные типы атрибутов. При таком подходе вы можете отправить несколько значений в поток пользовательского интерфейса в разное время. Вы можете запустить (отправить) много Runnable
объектов на этом HandlerThread
, и каждый Runnable
может установить значение в объекте Message
, которое может быть получено в потоке пользовательского интерфейса.
Обычно вы делаете это примерно так:
public class Foo implements Runnable {
private volatile int value;
@Override
public void run() {
value = 2;
}
public int getValue() {
return value;
}
}
Затем вы можете создать поток и получить значение (учитывая, что значение было установлено)
Foo foo = new Foo();
new Thread(foo).start();
// ... join through some method
int value = foo.getValue();
tl;dr
нить не может вернуть значение (по крайней мере, без механизма обратного вызова). Вы должны ссылаться на поток как обычный класс и запрашивать значение.
The method getValue() is undefined for the type Thread
.
– pmichna
26 November 2013 в 17:07
t.getValue()
на foo.getValue()
.
– Johan Sjöberg
26 November 2013 в 17:46
Thread t = new Thread(foo); t.start(); t.join(); foo.getValue();
. t.join()
блокируется до тех пор, пока поток не будет завершен.
– Daniel
16 December 2014 в 18:03
Если вы хотите получить значение из вызывающего метода, тогда он должен дождаться завершения потока, что делает использование потоков немного бессмысленным.
Чтобы напрямую ответить на ваш вопрос, значение может быть сохранено в любой изменяемый объект, как вызывающий, так и поток, имеет ссылку. Вы можете использовать внешний this
, но это не будет особенно полезно, кроме как для тривиальных примеров.
Небольшое примечание к коду в вопросе: Расширение Thread
обычно плохое. , Действительно, расширение классов без необходимости - плохая идея. Я заметил, что метод run
синхронизирован по какой-то причине. Теперь, поскольку объектом в этом случае является Thread
, вы можете вмешиваться в то, что Thread
использует свою блокировку для (в ссылочной реализации, что-то делать с join
, IIRC).
Java 8 обеспечивает CompletableFuture. это будет единственным решением для этого. http://www.baeldung.com/java-completablefuture