멀티스레딩에서 하위 스레드가 메인 스레드 UI를 업데이트하는 방법과 주의사항은 무엇인가요?
Android
UI 멀티스레드 Androidthread 작업
Android 프로그램이 실행되면 별도로 프로세스가 시작됩니다. 기본적으로 이 프로그램의 모든 활동 또는 서비스(서비스 및 활동은 콘텐츠 제공자 및 브로드캐스트 수신기 외에 Android에서 제공하는 두 가지 구성요소임)가 이 프로세스에서 실행됩니다.
Android 프로그램에는 기본적으로 하나의 프로세스만 있지만 하나의 프로세스 아래에는 여러 개의 스레드가 있을 수 있습니다. 수많은 스레드 중에 하나의 스레드가 있는데, 이를 UI 스레드라고 합니다. UI 스레드는 Android 프로그램이 실행될 때 생성되며 주로 UI 인터페이스의 표시, 업데이트 및 제어 상호 작용을 담당하는 메인 스레드입니다. Android 프로그램 생성 초기에는 프로세스가 단일 스레드 모델을 제시했으며 모든 작업이 하나의 스레드에서 실행되었습니다. 따라서 우리는 UI 스레드가 실행하는 각 함수에 소요되는 시간을 최대한 줄여야 한다고 믿습니다. 시간이 많이 걸리는 다른 작업(네트워크 액세스, 데이터 다운로드, 데이터베이스 쿼리 등)은 기본 스레드를 차단하지 않도록 하위 스레드에서 수행해야 합니다.
그렇다면 UI 스레드는 다른 스레드와 어떻게 작동합니까? 일반적으로 사용되는 방법은 다음과 같습니다.
메인 스레드의 Handler 객체를 생성하고 이를 리스너로 사용하여 하위 스레드가 메인 스레드의 Message Quene에 메시지를 푸시하여 handlerMessage를 트리거할 수 있도록 합니다. () 함수를 사용하여 메인 스레드가 하위 스레드의 상태를 파악하고 메인 스레드의 UI를 업데이트하도록 합니다.
예를 들어 하위 스레드의 상태가 변경되면 UI를 업데이트해야 합니다. UI가 하위 스레드에서 직접 업데이트되는 경우 일반적으로 다음 예외가 발생합니다. 11-07 13:33:04.393: ERROR/JavaBinder(1029): android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that create a 뷰 계층 구조는 해당 뷰를 터치할 수 있습니다.
즉, 하위 스레드에서는 UI를 업데이트할 수 없습니다. 이를 위해서는 Handler 객체를 통해 인터페이스를 업데이트하도록 메인 스레드 Ui Thread에 알려야 합니다.
다음과 같이 먼저 메시지 이벤트를 수신하는 핸들러를 만듭니다.
private final int UPDATE_UI = 1;private Handler mHandler = new MainHandler();private class MainHandler extends Handler {@ Overridepublic void handlerMessage(Message msg) {switch (msg.what) {case UPDATE_UI: {Log.i("TTSDeamon", "UPDATE_UI");showTextView.setText(editText.getText().toString());ShowAnimation() ;break;}default:break;}}}
또는
private Handler mHandler = new Handler(){@Overridepublic void handlerMessage(Message msg) {switch (msg.what) {case UPDATE_UI: {Log.i("TTSDeamon", "UPDATE_UI");showTextView.setText(editText.getText().toString());ShowAnimation();break;}default:break;}}}
하위 스레드의 상태가 변경되면 하위 스레드에 메시지를 보내 UI 업데이트를 알립니다.
mHandler.sendEmptyMessageDelayed(UPDATE_UI, 0);
우리 프로그램에서 많은 콜백 메서드가 메인 스레드에서 실행되지 않는 경우가 있으므로 콜백 메서드에서 업데이트하면 UI가 실패하는 경우 , 위의 방법을 사용할 수도 있습니다.