Here is a real life example when HandlerThread becomes convenient. When you register in the camera preview frame, you get them in the onPreviewFrame() . The documentation explains that this callback is called in the open (int) event stream called from .
This usually means that the callback will be called in the main thread (UI). Thus, the task of working with huge arrays of pixels may depend on opening the menu, animating the animation, or even with statistics printed on the screen.
A simple solution is to create new HandlerThread() and delegate Camera.open() to this thread (I did this via post(Runnable) , you do not need to implement Handler.Callback ).
Please note that all other work with the camera can be performed as usual, you do not need to delegate Camera.startPreview() or Camera.setPreviewCallback() to HandlerThread. To be safe, I expect Camera.open(int) to actually complete before continuing with the main thread (or some 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"); }
first extract it as is in 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() just 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"); } } }
Please note that the whole chain of notify () - wait () is not required if you do not get access to mCamera in the source code immediately after opening it.
Update: Here the same approach applies to the accelerometer: The accelerometer sensor in a separate topic
Alex Cohn Oct 03 '13 at 8:33 2013-10-03 08:33
source share