当前位置: 首页 > 知识库问答 >
问题:

最佳使用HandlerThread优于其他类似类

谭梓
2023-03-14

我正在尝试了解使用HandlerThread的最佳用例。

根据定义:

“方便的类,用于启动具有循环器的新线程。然后,可以使用循环器来创建处理程序类。请注意,仍必须调用 start()。

我可能是错的,但我可以通过使用线程活包处理程序来实现类似的功能。那么我什么时候应该使用HandlerThread呢?举个例子会很有帮助。

共有2个答案

侯令雪
2023-03-14

这是HandlerThread和Looper源代码的链接。

如果你看一下这两个代码,你会发现< code>HandlerThread正如它所说的那样,是一种启动具有< code>Looper的< code >线程的便捷方式。为什么会存在这种情况?因为线程在默认情况下没有消息循环。< code>HandlerThread只是创建一个简单的方法。你能用< code>Handler 、< code>Thread和< code>Looper复制这个函数吗——从源代码来看——答案是肯定的。

遗嘱执行人是不同的。执行器接受提交的可运行任务,并 - 猜测 - 执行它们。为什么这是必要的?它允许您将任务的执行与其实际内容分离。你什么时候会用这个?假设您遇到需要同时执行多个任务的情况。您可以选择使用执行程序在单个线程上运行它们,以便按顺序执行它们。或者,您可以使用固定的线程池,以便同时运行一些(但不是全部)。在任何一种情况下,任务的实质 - 即它实际在做什么 - 都与执行它的方式是分开的。

叶琦
2023-03-14

这里是一个真实的示例,其中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中的项列表?