我正在通过一本教科书的例子学习如何在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中,我们调用
getApp().getExecutors().diskIO().execute(() -> {
...
}
哪里 getApp().getExecutors()
返回的新示例 AppExecutors
.
我的问题是:
我明白 getApp().getExecutors().mainThread().execute(() -> {...}
传递一个新的runnable,并将此runnable提供给主线程的messagequeue。循环器将每个线程从消息队列中取出并执行它。
然而,情况不同 getApp().getExecutors().diskIO().execute(() -> {...}
. 传递给它的runnable显然是在后台线程中执行的。 Executors.newSingleThreadExecutor()
似乎打开了一条新的思路。但没有与此线程关联的处理程序或messagequeue。所以,我想知道,这个线程在执行后不会被关闭吗?一旦线程关闭,我们就不能再次打开同一个线程。这对我来说有点困惑,线不应该保持开放吗?我现在已经阅读了Executor服务,显然这个服务只是让线程保持打开状态。但话说回来,这不是messageque和处理程序正在做的事情吗?那么这有什么不同呢?
2条答案
按热度按时间pn9klfpd1#
下面是一个修改appexecutors类的示例。您可以看到,我们没有使用单个线程执行器,而是使用了后台处理程序线程,我们创建了一个处理程序对象,然后将其绑定到handlerthread对象。此外,对于主线程执行,我们删除了 Package 器类并创建了另一个处理程序对象,然后将其绑定到主线程的循环器。我希望你一切都清楚
以下是新appexecutors类的一些示例用法片段:
还要注意的是,handlerthread和handler api属于google的android.os包。因此,您将无法在非为android操作系统编写的应用程序中使用它们。以上就是这个例子,祝你学业成功。
r6l8ljro2#
我认为这个答案将部分回答你的问题。另外,对于您的问题:
所以,我想知道,这个线程在执行后不会被关闭吗?一旦线程关闭,我们就不能再次打开同一个线程。这对我来说有点困惑,线不应该保持开放吗?
不,不会的。该executor服务的线程将处于空闲或阻塞状态,直到您将新的runnable排队,因为它使用blockingqueue。如果队列为空,线程将被阻塞,如果runnale对象到达其队列,线程将被激活。如您所见,executorservice没有活套。只有在调用executorservice的shutdown()或shutdownnow()方法时,它才会被销毁。
但话说回来,这不是messageque和处理程序正在做的事情吗?那么这有什么不同呢?
相反,处理程序需要绑定到循环器才能发送消息和发布可运行文件,而循环器则位于handlerthread中。handlerthread对应于单线程执行器服务,其处理程序对应于执行器。在appexecutors类中,处理程序绑定到主线程的循环器,因为ui对象不能从创建它的主线程以外的线程进行触摸。
让我们看看示例java代码中的区别。使用executorservice的后台线程示例。
使用handlerthread的后台线程示例:
handler api只是android特有的api,它有许多用于发送和处理消息对象和可运行命令的实用程序。有关更多信息,请参阅处理程序api。