gpt4 book ai didi

android - Android 中 SingleThreadExecutor 和 Handler 之间的区别(通过示例)

转载 作者:行者123 更新时间:2023-12-04 07:20:40 26 4
gpt4 key购买 nike

我正在研究如何使用 Android 中的 Room 将数据写入 SQlite 数据库的教科书示例。显然,我们不能从主线程将数据写入数据库,但我们需要一个后台线程。在我的书中,我们所做的是,我们创建一个额外的类 AppExecutors内容如下:

public class AppExecutors {
private final Executor _diskIO;
private final Executor _networkIO;
private final Executor _mainThread;

private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
_diskIO = diskIO;
_networkIO = networkIO;
_mainThread = mainThread;
}

public AppExecutors() {
this(Executors.newSingleThreadExecutor(),
Executors.newFixedThreadPool(3),
new MainThreadExecutor());
}

public Executor diskIO() {
return _diskIO;
}


public Executor networkIO() {
return _networkIO;
}

public Executor mainThread() {
return _mainThread;
}

private static class MainThreadExecutor implements Executor {
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());

@Override
public void execute(Runnable command) {
mainThreadHandler.post(command);
}
}
}
然后,在 MainActivity 内部,它也包含 UI,即按钮,它在单击时触发一个 Action ,我们调用
getApp().getExecutors().diskIO().execute(() -> {
...
}
在哪里 getApp().getExecutors()返回 AppExecutors 的新实例.
这是我的问题:
我明白 getApp().getExecutors().mainThread().execute(() -> {...}传递一个新的 Runnable,并将这个 Runnable 提供给主线程的消息队列。 looper 将每个线程从消息队列中取出并执行。
然而, getApp().getExecutors().diskIO().execute(() -> {...} 的情况有所不同。 .
传递给它的 Runnable 显然是在后台线程中执行的。 Executors.newSingleThreadExecutor()似乎开辟了一个新的线程。但是没有与该线程关联的处理程序或消息队列。所以,我想知道,这个线程在执行后不会关闭吗?一旦线程关闭,我们就不能再次打开同一个线程。这对我来说有点困惑,线程不应该保持打开状态吗?
我现在已经阅读了 ExecutorService ,显然这个服务只是让线程保持打开状态。但是话又说回来,这不是消息队列和处理程序正在做的事情吗?那么这有什么不同呢?

最佳答案

我认为 this answer将部分回答您的问题。另外对于您的问题:

So, I was wondering, won't this thread be closed after execution? Once the thread is closed, we cannot open the same thread again. And that's a bit confusing for me, shouldn't the thread stay open?


不,不会的。该执行程序服务的线程将处于空闲或阻塞状态,直到您将新的可运行对象排队,因为它使用 BlockingQueue。如果队列为空,线程将被阻塞,如果 Runnale 对象到达其队列,线程将被激活。如您所见 ExecutorService 没有 Looper .仅当您调用 ExecutorService 的 shutdown() 或 shutdownNow() 方法时,它才会被销毁。

But then again, isn't this the same thing that the messageque and the handler are doing? So how is this different?


相比之下,Handler 需要绑定(bind)到 Looper 才能发送消息和发布 Runnables,而 Looper 则存在于 HandlerThread 中。一个HandlerThread对应一个单线程的Executor服务,它的Handler对应一个Executor。在 AppExecutors 类中,一个 Handler 与主线程的 Looper 相关联,因为 UI 对象不能从创建它的主线程以外的线程中被触及。
让我们看看示例 Java 代码的区别。
使用 ExecutorService 的后台线程示例。
/*
To create a background thread making use of the Java concurrent API first we
need to create an ExecutorService or only Executor if you don't want to manage
the service. But generally it must be shutdown when we are done with it.
That's why we need a reference to the ExecutorService in orderto shutdown it.
*/
ExecutorService executorService = Executors.newSingleThreadExecutor();
Executor executor = executorService;

// To send a command:
executor.execute(someRunnable);
// As you can see an executor has only the execute method.

// After we are done with executor service we must shutdown it.
executorService.shutdown();
// or
executorService.shutdownNow();
// This returns a list of runnables that were in the queue.

使用 HandlerThread 的后台线程示例:
/*
To create a background thread which has a message queue we have to make
use of the Android's HandlerThread and Handler API. A HandlerThread object
manages a Looper and a Thread in it while A Handler object is used to send
commands or messages to a living HandlerThread object.
*/
// A HandlerThread can also be instantiated with a name and a priority.
HandlerThread handlerThread = new HandlerThread();
handlerThread.start(); // Must call start in contras to an ExecutorService

// Tie this handler to the handlerThread's Looper so that we can send
// commands or messages to its queue.
Handler handler = new Handler(handlerThread.getLooper());

// To send a command
handler.post(someRunnable); // or
handler.postDelayed(someRunnable, delayInMillis); // or
handler.postAtFrontOfQueue(someRunnable); // or
handler.postAtTime(someRunnable, upTimeInMillis);
Handler API 只是 Android 特定的 API,并且有许多实用程序来发送和处理 Message 对象和 Runnable 命令。见 Handler API 以获取更多信息。

关于android - Android 中 SingleThreadExecutor 和 Handler 之间的区别(通过示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68520927/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com