IT Share you

다른 유사한 클래스보다 HandlerThread를 가장 잘 사용

shareyou 2020. 11. 11. 20:54
반응형

다른 유사한 클래스보다 HandlerThread를 가장 잘 사용


을 (를) 사용하는 최상의 사용 사례를 이해하려고합니다 HandlerThread.

정의에 따라 :

"루 퍼가있는 새 스레드를 시작하기위한 편리한 클래스입니다. 그런 다음 루퍼를 사용하여 핸들러 클래스를 만들 수 있습니다. start ()를 계속 호출해야합니다."

내가 틀렸을 수도 있지만 Thread, LooperHandler. 그래서 언제 사용해야 HandlerThread합니까? 예가 정말 도움이 될 것입니다.


다음은 HandlerThread 가 편리한 실제 사례 입니다. 카메라 미리보기 프레임에 등록하면 onPreviewFrame()콜백으로 수신됩니다 . 문서는 것을 설명 이 콜백에서 호출 된 이벤트 스레드 개방 (INT)에 호출됩니다 .

일반적으로 이는 콜백이 기본 (UI) 스레드에서 호출됨을 의미합니다. 따라서 메뉴가 열리거나 애니메이션이 애니메이션되거나 화면에 통계가 인쇄되는 경우에도 거대한 픽셀 배열을 처리하는 작업이 중단 될 수 있습니다.

쉬운 해결책은 이 스레드 를 생성 new HandlerThread()하고 위임 Camera.open()하는 것입니다 (을 통해 post(Runnable)수행 했으므로 구현할 필요가 없습니다 Handler.Callback).

Camera와 관련된 다른 모든 작업은 평소와 같이 수행 할 수 있으며 HandlerThread Camera.startPreview()또는 위임 할 필요가 없습니다 Camera.setPreviewCallback(). 안전한 편이 되려면 주 스레드 (또는 변경 전에 호출하는 데 사용 된 스레드)를 계속하기 전에 실제 작업 이 완료 될 때까지 기다립니다 .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을 을 연 후 즉시 원래의 코드.

업데이트 : 여기에서는 가속도계에 동일한 접근 방식이 적용됩니다. 별도 스레드의 가속도계 센서


다음은 HandlerThreadLooper 의 소스 코드에 대한 링크 입니다.

If you look at the two you will see that a HandlerThread is exactly what it says it is - a convenient way to start a Thread that has a Looper. Why does this exist? Because threads, by default do not have a message loop. The HandlerThread is just an easy way to create one that does. Could you duplicate this function with Handler, Thread, and Looper - judging from the source code - the answer is yes.

An Executor is different. An Executor takes submitted runnable tasks and - guess what -executes them. Why is this necessary? It allows you to decouple the execution of the task from its actual substance. When would you use this? Say you had a situation that required executing multiple tasks at the same time. You could choose, using an Executor, to run them all on a single thread so that they are executed serialy. Or you could use a fixed thread pool so that some, but not all are run at the same time. In either case the substance of the task - i.e. what it's actually doing - is seperate from the manner in which it is being executed.

참고URL : https://stackoverflow.com/questions/18149964/best-use-of-handlerthread-over-other-similar-classes

반응형