为了账号安全,请及时绑定邮箱和手机立即绑定

最好使用HandlerThread而不是其他类似的类

/ 猿问

最好使用HandlerThread而不是其他类似的类

尚方宝剑之说 2019-10-12 11:07:37

最好使用HandlerThread而不是其他类似的类

我试图了解使用的最佳用例HandlerThread

根据定义:

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

我可能是错的,但类似的功能,我可以通过使用实现ThreadLooperHandler。那么我HandlerThread什么时候应该使用?一个例子真的很有帮助


查看完整描述

2 回答

?
隔江千里

这是HandlerThread变得方便的真实例子。注册Camera预览帧时,您会在onPreviewFrame()回调中收到它们。该文档解释了在调用事件线程open(int)时调用此回调

通常,这意味着将在主(UI)线程上调用回调。因此,当打开菜单,动画动画或甚至在屏幕上打印统计数据时,处理巨大像素阵列的任务可能会卡住。

简单的解决方案是创建一个new HandlerThread()并委托Camera.open()给这个线程(我做到了post(Runnable),你不需要实现Handler.Callback)。

请注意,使用Camera的所有其他工作可以照常完成,您不必委托Camera.startPreview()Camera.setPreviewCallback()处理HandlerThread。为了安全起见,我等待实际Camera.open(int)完成,然后继续主线程(或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,则不需要整个notify() - wait()线程间通信。

更新:这里采用相同的方法加速度计:单独螺纹中的Acclerometer传感器



查看完整回答
反对 回复 2019-10-13
?
慕雪6442864

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

如果你看看这两个,你会发现它HandlerThread正是它所说的 - 一种方便的方式来启动Thread它有一个Looper。为什么会这样?因为线程默认没有消息循环。这HandlerThread只是创建一个简单的方法。你可以用HandlerThreadLooper- 从源代码判断复制这个功能- 答案是肯定的。

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



查看完整回答
反对 回复 2019-10-13

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信