Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best use of HandlerThread over other similar classes

I am trying to understand the best use case of using HandlerThread.

As per definition:

"Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called."

I may be wrong but similar functionality I can achieve by using a Thread, Looper and Handler. So when should I use HandlerThread? An example would be really helpful.

like image 410
Androidme Avatar asked Aug 09 '13 15:08

Androidme


People also ask

What is the difference between handler and HandlerThread?

Threads are generic processing tasks that can do most things, but one thing they cannot do is update the UI. Handlers on the other hand are background threads that allow you to communicate with the UI thread (update the UI).

How do you use HandlerThread?

How do I use HandlerThreads. There are 2 main ways that I found to use HandlerThreads. Create a new HandlerThread, create a new Handler using this HandlerThread and post your tasks on this handler. Extend HandlerThread inside your CustomHandlerThread, create a Handler to process your task.

What is the difference between thread and HandlerThread in Android?

The main difference between Handler and Thread is that a handler is a function or a method that is capable of performing a specific task while a thread is a small, lightweight execution unit within a process.

What is HandlerThread?

android.os.HandlerThread. A Thread that has a Looper . The Looper can then be used to create Handler s. Note that just like with a regular Thread , Thread.


1 Answers

Here is a real life example where HandlerThread becomes handy. When you register for Camera preview frames, you receive them in onPreviewFrame() callback. The documentation explains that This callback is invoked on the event thread open(int) was called from.

Usually, this means that the callback will be invoked on the main (UI) thread. Thus, the task of dealing with the huge pixel arrays may get stuck when menus are opened, animations are animated, or even if statistics in printed on the screen.

The easy solution is to create a new HandlerThread() and delegate Camera.open() to this thread (I did it through post(Runnable), you don't need to implement Handler.Callback).

Note that all other work with the Camera can be done as usual, you don't have to delegate Camera.startPreview() or Camera.setPreviewCallback() to the HandlerThread. To be on the safe side, I wait for the actual Camera.open(int) to complete before I continue on the main thread (or whatever thread was used to call Camera.open() before the change).


So, if you start with code

try {     mCamera = Camera.open(1); } catch (RuntimeException e) {     Log.e(LOG_TAG, "failed to open front camera"); } // some code that uses mCamera immediately 

first extract it as is into a private method:

private void oldOpenCamera() {     try {         mCamera = Camera.open(1);     }     catch (RuntimeException e) {         Log.e(LOG_TAG, "failed to open front camera");     } } 

and instead of calling oldOpenCamera() simply use 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");         }     } } 

Note that the whole notify() -- wait() inter-thread communication is not necessary if you don't access mCamera in the original code immediately after opening it.

Update: Here the same approach is applied to accelerometer: Acclerometer Sensor in Separate Thread

like image 60
Alex Cohn Avatar answered Oct 03 '22 02:10

Alex Cohn