我正在尝试了解使用HandlerThread
的最佳用例。
根据定义:
“方便的类,用于启动具有循环器的新线程。然后,可以使用循环器来创建处理程序类。请注意,仍必须调用 start()。
我可能是错的,但我可以通过使用线程
,活包
和处理程序
来实现类似的功能。那么我什么时候应该使用HandlerThread呢
?举个例子会很有帮助。
这是HandlerThread和Looper源代码的链接。
如果你看一下这两个代码,你会发现< code>HandlerThread正如它所说的那样,是一种启动具有< code>Looper的< code >线程的便捷方式。为什么会存在这种情况?因为线程在默认情况下没有消息循环。< code>HandlerThread只是创建一个简单的方法。你能用< code>Handler 、< code>Thread和< code>Looper复制这个函数吗——从源代码来看——答案是肯定的。
遗嘱执行人
是不同的。执行器
接受提交的可运行任务,并 - 猜测 - 执行它们。为什么这是必要的?它允许您将任务的执行与其实际内容分离。你什么时候会用这个?假设您遇到需要同时执行多个任务的情况。您可以选择使用执行程序
在单个线程上运行它们,以便按顺序执行它们。或者,您可以使用固定的线程池,以便同时运行一些(但不是全部)。在任何一种情况下,任务的实质 - 即它实际在做什么 - 都与执行它的方式是分开的。
这里是一个真实的示例,其中HandlerThread变得非常方便。当您注册相机预览帧时,您将在<code>onPreviewFrame()这个回调是在从调用事件线程open(int)时调用的。
通常,这意味着将在主 (UI) 线程上调用回调。因此,当菜单打开,动画动画,甚至在屏幕上打印统计数据时,处理巨大像素数组的任务可能会卡住。
简单的解决方案是创建一个new HandlerThread()
并将Camera.open()
委托给这个线程(我是通过post(Runnable)
完成的,您不需要实现Handler.Callback
)。
请注意,相机的所有其他工作都可以照常完成,您不必委托相机。startPreview()
或摄像机。将PreviewCallback()
设置为HandlerThread。为了安全起见,我等待实际的摄像机。打开(int)
以完成,然后在主线程上继续(或在更改之前用于调用<code>Camera.open()
所以,如果你从代码开始
try {
mCamera = Camera.open(1);
}
catch (RuntimeException e) {
Log.e(LOG_TAG, "failed to open front camera");
}
// some code that uses mCamera immediately
首先将其按原样提取到私有方法中:
private void oldOpenCamera() {
try {
mCamera = Camera.open(1);
}
catch (RuntimeException e) {
Log.e(LOG_TAG, "failed to open front camera");
}
}
而不是调用oldOpenCamera()
只需使用newOpencamera()
:
private void newOpenCamera() {
if (mThread == null) {
mThread = new CameraHandlerThread();
}
synchronized (mThread) {
mThread.openCamera();
}
}
private CameraHandlerThread mThread = null;
private static class CameraHandlerThread extends HandlerThread {
Handler mHandler = null;
CameraHandlerThread() {
super("CameraHandlerThread");
start();
mHandler = new Handler(getLooper());
}
synchronized void notifyCameraOpened() {
notify();
}
void openCamera() {
mHandler.post(new Runnable() {
@Override
public void run() {
oldOpenCamera();
notifyCameraOpened();
}
});
try {
wait();
}
catch (InterruptedException e) {
Log.w(LOG_TAG, "wait was interrupted");
}
}
}
请注意,如果您在打开后没有立即访问原始代码中的mCamera,则不需要整个通知()-等待()线程间通信。
更新:这里相同的方法适用于加速度计:加速度计传感器在单独的线程中
我被要求实现这个函数,它等待一些操作完成。然后让它做它应该做的事情。我被要求不要使用观察者类。我尝试了无限循环,它成功了。所以我想知道是否还有其他方法可以做到这一点。(我正在Jade中开发一个应用程序,超级代理与其他代理进行通信,一旦代理收到消息,他就可以执行一些功能并发送回消息)。我想为等待的部分做点什么。提前感谢
注:内容翻译自官网文档 Language Guide (proto3) 中的 Using Other Message Types 一节 可以使用其他消息类型作为字段类型. 例如, 假设你想在每个SearchResponse消息中包含Result消息 - 为了做到这点, 你可以在相同的.proto文件中定义Result消息类型然后具体指定SearchResponse中的一个字段为Result类型:
问题内容: 如果我有两个类,而其中一个有一个要在其他类中使用的函数,那么该使用什么,这样就不必重写我的函数了? 问题答案: 有两种选择: 在您的类中实例化一个对象,然后在其上调用所需的方法 使用@classmethod将函数转换为类方法 例: 或使用继承(如果适用):
问题内容: 我正在为Web应用程序编写日志文件查看器,为此,我想在日志文件的各行中进行分页。文件中的项目是基于行的,底部是最新的项目。 因此,我需要一种可以n从底部读取行并支持偏移量的方法。我想到的是这样的: 这是合理的方法吗?建议使用带偏移量尾部日志文件的推荐方式是什么? 问题答案:
我有一个很大的问题,我不知道我是否错过了一些明显的东西或什么,但我不能发现我的错误。我有类SPN、A和B。我重载了2次operator=。我想将A类型或B类型作为参数传递。 它不会抛出任何错误。但是如果我在类B或A中尝试make operator(),则使用参数SPN,如下所示: 它会抛出SPN未命名类型的错误。我甚至不能在A类或B类中创建类SPN对象。也许它不是如何客观编程工作,所以我想得到它,
Firebase onMessageReceived方法提供remoteMessage实例以获取发送的消息或通知。如何将remoteMessage实例从扩展FirebaseMessagingService的类发送到RecolyerViewAdapter以更新RecolyerView中的项列表?