简体   繁体   English

与 Android 线程、处理程序和处理程序线程的并发性

[英]Concurrency with Android Thread, Handler and HandlerThreads

Ok.好的。 So I'm working with the Camera2 API and trying to process all the work in the background so the UI is responsive.所以我正在使用 Camera2 API 并尝试在后台处理所有工作,以便 UI 响应。 I have implemented a HandlerThread and a Handler to put tasks in it like so:我已经实现了一个 HandlerThread 和一个 Handler 来将任务放入其中,如下所示:

    private void startBackgroundThread(){
         backgroundHandlerThread = new HandlerThread("BackgroundThread");
         backgroundHandlerThread.start();
         backgroundHandler = new Handler(backgroundHandlerThread.getLooper());
    }

Then I post the runnables like so:然后我像这样发布可运行文件:

    backgroundHandler.post(new ImageSaver(reader.acquireLatestImage()));

The problem is that I use the same handler (backgroundHander) for every runnable I post and I'm getting some serious performance issues.问题是我对发布的每个可运行文件都使用相同的处理程序(backgroundHander),并且遇到了一些严重的性能问题。 That tells me that I'm not doing concurrency correctly but I'm incapable of finding the correct use of these classes after looking at the docs for several hours.这告诉我,我没有正确地进行并发,但是在查看文档几个小时后,我无法找到这些类的正确用法。 What is the correct approach?什么是正确的方法?

  • Creating multiple Handlers for each runnable I post in the HandlerThread?为我在 HandlerThread 中发布的每个可运行文件创建多个处理程序?
  • Creating multiple HandlerThread for each type of runnable?为每种类型的可运行对象创建多个 HandlerThread?

Thanks in advance and try not to be harsh on me because I'm pretty noob at this.在此先感谢并尽量不要对我苛刻,因为我对此很陌生。

Every HandlerThread has a Looper which runs a messsage loop for the thread.每个HandlerThread都有一个Looper ,它为线程运行一个消息循环。 Each Looper has a MessageQueue which holds the list of messages being sent to the Looper.每个 Looper 都有一个MessageQueue ,它保存着发送到 Looper 的消息列表。 Messages and Runnables are sent to the MessageQueue by a Handler .消息和 Runnable 由Handler发送到 MessageQueue。 Each one is executed as they come out of the message queue.每一个都在它们从消息队列中出来时被执行。 This process is what is preventing you from "true" concurrency.这个过程是阻止您“真正”并发的原因。

An ExecutorService could work here. ExecutorService可以在这里工作。 An ExecutorService allows multiple Runnables to be submitted and executed. ExecutorService 允许提交和执行多个 Runnable。 From your code snippets above it appeared as though you were using the HandlerThread to put work in the background off the Main or UI Thread.从上面的代码片段来看,好像您正在使用 HandlerThread 将工作置于主线程或 UI 线程的后台。 If you are not attempting to relay the work or its result back to the Main Thread, a regular thread and thus an ExecutorService would work as well.如果您不尝试将工作或其结果传递回主线程,则常规线程和 ExecutorService 也可以正常工作。

As an Example举个例子

...
Executor executor = Executors.newFixedThreadPool(numThreads);
executor.submit(new ImageSaver(reader.acquireLatestImage()));
// submit Runnables as needed
executor.shutdownNow(); // VERY IMPORTANT OR YOU WILL CREATE A MEMORY LEAK!
...

If you need to communicate back to the UI thread, you will need to provide an implementation of the ExecutorService interface like the example in the ExecutorService Usage Examples section of its documentation.如果您需要与 UI 线程进行通信,则需要提供 ExecutorService 接口的实现,如其文档的ExecutorService使用示例部分中的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM