我想在后台线程中运行一些Runnable。我想使用Handler,因为它很方便延迟。 我的意思是
handler.post(runnable, delay);
可运行应在后台主题中运行。 是否可以创建这样的Handler? 在某处有“背景”Looper或者我该如何创建它?
P.S。我知道如何使用自定义类扩展Thread,但它需要比处理程序方式更多的编码工作。所以请不要发布其他解决方案或类似的东西
handler.post(new Runnable() {
@Override
public void run() {
new Thread() {
@Override
public void run() {
//action
}
}.start();
}
});
如果Handler能够以“干净”的方式做到这一点,我就会徘徊。
答案 0 :(得分:65)
你可以这样做:
private Handler mHandler = null;
private HandlerThread mHandlerThread = null;
public void startHandlerThread(){
mHandlerThread = new HandlerThread("HandlerThread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
}
然后用:
调用handler.postDelayed(new Runnable(),1000);
答案 1 :(得分:8)
您可以尝试这样的事情
private void createHandler() {
Thread thread = new Thread() {
public void run() {
Looper.prepare();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
// Do Work
handler.removeCallbacks(this);
Looper.myLooper().quit();
}
}, 2000);
Looper.loop();
}
};
thread.start();
}
答案 2 :(得分:5)
您可以使用Looper.prepare()
和Looper.loop
在后台主题中设置Looper。
答案 3 :(得分:0)
Handler
并不清楚你的意思。
听起来你需要一个线程来处理队列执行的进程。您可能会从调查Executor
s here中受益,但这是一个通过队列进行通信的简单双线程对。
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final Queue<Integer> queue;
public Producer(Queue<Integer> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final Queue<Integer> queue;
public Consumer(Queue<Integer> queue) {
this.queue = queue;
}
@Override
public void run() {
boolean ended = false;
while (!ended) {
Integer i = queue.poll();
if (i != null) {
ended = i == End;
System.out.println(i);
}
}
}
}
public void test() throws InterruptedException {
Queue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
答案 4 :(得分:0)
我在kotlin中实现了在后台线程上运行任务的简单方法:
fun background(function: () -> Unit) = handler.post(function)
private val handler: Handler by lazy { Handler(handlerThread.looper) }
private val handlerThread: HandlerThread by lazy {
HandlerThread("RenetikBackgroundThread").apply {
setUncaughtExceptionHandler { _, e -> later { throw RuntimeException(e) } }
start()
}
}
通常的想法是,任务很容易执行,并且一个接一个的顺序执行,并且未捕获的异常会传播到主线程,这样它们就不会丢失。以后的功能基本上是在主线程上运行的处理程序。
因此您可以像这样简单地发布任务:
background {
some task to do in background...
}
科德
background {
other task to do in background...
later {
on main thread when all tasks are finished...
}
}