我想我已经看到一些实现方式。基本思路大致是
class UiThreadExecutor implements Executor { private final Handler mHandler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable command) { mHandler.post(command); }}通过将其传递给主线程的处理程序,您可以委派运行任何内容。
编辑:例如https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/android/MainThreadExecutor.java
Edit2:您可以配置处理程序,例如
SensorManager#registerListener(..., Handlerhandler)允许您这样做。
class HandlerThreadExecutor implements Executor { private final Handler mHandler; public HandlerThreadExecutor(Handler optionalHandler) { mHandler = optionalHandler != null ? optionalHandler : new Handler(Looper.getMainLooper()); } @Override public void execute(Runnable command) { mHandler.post(command); }}与使用当前线程的循环程序相比,其优势在于,它可以使您明确
Looper使用哪个线程。在您的解决方案中,无论线程调用什么,您都可以使用Looper-
new ExecuteonCaller()而且通常不是您稍后运行代码的线程。
我很高兴知道如何仅使用纯Java就无需使用诸如Handler和Looper之类的Android特有的东西就能达到相同的效果。
Looper,
Handler和后面所有的逻辑消息队列由大多纯Java的。通用解决方案的问题在于,您无法“注入”代码以运行到线程中。线程必须定期检查某种任务队列,以查看是否有要运行的东西。
如果您编写类似的代码
new Thread(new Runnable() { @Override public void run() { while (!Thread.interrupted()) { System.out.println("Hello"); } } }).start();然后,除了不断打印“
Hello”之外,没有其他方法可以使该线程执行任何其他操作。如果可以的话,这就像在程序代码中动态插入到其他代码的跳转一样。IMO将是一个可怕的想法。
final BlockingQueue<Runnable> queue = new linkedBlockingQueue<Runnable>(); new Thread(new Runnable() { @Override public void run() { try { while (true) { Runnable preToRunInThisThread = queue.take(); preToRunInThisThread.run(); } } catch (InterruptedException ignored) {} } }).start();另一方面,一个简单的线程会在队列中永远 循环 。该线程可以在两者之间执行其他任务,但是您必须在代码中添加手动检查。
您可以通过发送任务
queue.put(new Runnable() { @Override public void run() { System.out.println("Hello!"); } });这里没有定义特殊的处理程序,但这是Handler&Looper在Android中所做的工作的核心。
Handler在Android中,您可以为
Message而不是定义回调
Runnable。
Executors.newCachedThreadPool()和类似的东西大致相同。在一个队列中只有多个线程在等待代码。
作为对此问题的扩展,是否可以做同样的事情,而不仅是使用UI线程,而是使用任何特定线程来调用异步方法?
通用答案是“否”。仅当有一种方法可以注入代码在该线程中运行时。



