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

我想了解使用HandlerThread的最佳用例。

根据定义:

“用于启动一个具有活套的新线程的方便类,活套可用于创建处理程序类,请注意start()仍然必须被调用。

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

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

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

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

请注意,使用Camera的所有其他工作都可以照常完成,您不必将Camera.startPreview()Camera.setPreviewCallback()委托给HandlerThread。 为了安全起见,在继续执行主线程(或在更改之前调用Camera.open()任何线程Camera.open()之前,我等待实际的Camera.open(int)完成。


所以,如果你从代码开始

 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传感器在分开的线程

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

如果你看看两者,你会看到一个HandlerThread正是它所说的 – 一个启动一个具有LooperThread的简便方法。 为什么这个存在? 因为线程,默认情况下没有消息循环 。 HandlerThread只是创建一个简单的方法。 你可以用HandlerThreadLooper复制这个函数 – 从源代码判断 – 答案是肯定的。

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