안 드 로 이 드 의 Handler 비동기 통신 체 제 를 깊이 이해 하 다.
해결 방법:Message Queue 메커니즘 은 하위 라인 과 UI 라인 의 통신 을 실현 할 수 있다.
이 메커니즘 은 Handler,Message Queue,Looper 를 포함한다.Handler 는 메시지/Runnable 대상 을 Looper 에 보 낼 수 있 습 니 다.이 메 시 지 를 소속 스 레 드 의 메시지 큐 에 넣 은 다음 Looper 는 메시지 큐 에 있 는 메시지/Runnable 대상 을 소속 스 레 드 에 있 는 Handler 로 자동 으로 방송 하고 받 은 메시지 나 Runnable 대상 을 Handler 에서 처리 합 니 다.
1、Handler
Handler 대상 을 만 들 때마다 생 성 된 스 레 드 에 자동 으로 연 결 됩 니 다.메 인 스 레 드 라면 기본적으로 Message Queue 를 포함 합 니 다.그렇지 않 으 면 메시지 큐 를 만들어 저장 해 야 합 니 다.
Handler 는 여러 스 레 드 통신 의 신사 이다.예 를 들 어 스 레 드 A 에서 A Handler 를 만 들 고 ALooper 를 연결 하 는 동시에 A 에 속 하 는 메시지 큐 AMessageQueue 를 만 듭 니 다.그리고 스 레 드 B 에서 A Handler 를 사용 하여 알 루 퍼 에 게 메 시 지 를 보 냅 니 다.알 루 퍼 는 메 시 지 를 AMessage Queue 에 저장 한 다음 에 A 스 레 드 에 있 는 A Handler 에 게 방송 합 니 다.메 시 지 를 받 으 면 처리 합 니 다.통신 을 실현 한다.
2、Message Queue
메 인 스 레 드 에 기본적으로 메시지 큐 가 포함 되 어 있 습 니 다.수 동 으로 만 들 필요 가 없습니다.하위 스 레 드 에 서 는 Looper.prepare()방법 을 사용 한 후 하위 스 레 드 에 looper 대상 이 있 는 지 확인 합 니 다.있 으 면 만 들 수 없습니다.스 레 드 마다 메시지 큐 만 있 기 때 문 입 니 다.없 으 면 하위 스 레 드 에 메시지 큐 를 만 듭 니 다.
3.handler 체 제 를 완전 하 게 만 듭 니 다.
Handler 클래스 는 Looper 지침 과 Message Queue 지침 을 포함 하고 Looper 에는 실제 Message Queue 와 현재 스 레 드 지침 이 포함 되 어 있 습 니 다.
다음은 UI 스 레 드 와 worker 스 레 드 에 대해 handler 생 성 과정 을 설명 합 니 다.
우선,handler 를 만 들 때 현재 스 레 드 에 looper 대상 이 포함 되 어 있 는 지 자동 으로 확인 합 니 다.포함 되 어 있 으 면 handler 내 메시지 대기 열 을 looper 내부 메시지 대기 열 로 가리 키 고 그렇지 않 으 면 이상 요청 을 던 져 looper.prepare()방법 을 실행 합 니 다.
- UI 스 레 드 에서 시스템 은 자동 으로 Looper 대상 을 만 들 었 기 때문에 new handler 를 직접 사용 하면 이 메커니즘 을 사용 할 수 있 습 니 다.
-worker 스 레 드 에서 handler 를 직접 만 들 면 실행 중 이상 을 던 집 니 다.즉,'스 레 드-value'맵 표를 통 해 현재 스 레 드 에 looper 대상 이 없 음 을 발견 합 니 다.그래서 Looper.prepare()방법 을 먼저 호출 해 야 합 니 다.prepare 방법 에서 ThreadLocal
handler 메커니즘
4.핵심
- handler 는 looper 와 메시지 큐 를 공유 하기 때문에 handler 가 메 시 지 를 보 내 면 열 에 들 어가 면 looper 는 직접 메 시 지 를 가 져 오 면 됩 니 다.
- 스 레 드 와 looper 맵 표:하나의 스 레 드 는 looper 대상 을 최대 로 매 핑 할 수 있 습 니 다.현재 스 레 드 에 looper 가 포함 되 어 있 는 지 확인 할 수 있 습 니 다.포함 되 어 있 으 면 새 looper 를 만 들 지 않 습 니 다.
5.이러한 체 제 를 바탕 으로 어떻게 스 레 드 격 리 를 실현 합 니까?즉,스 레 드 에서 통신 합 니까?
핵심 은 모든 스 레 드 가 자신의 handler,message quue,looper 체 계 를 가지 고 있다 는 것 이다.각 스 레 드 의 핸들 러 는 공개 됐다.B 스 레 드 는 A 스 레 드 의 handler 를 호출 하여 A 의 공유 메시지 대기 열 로 메 시 지 를 보 낼 수 있 습 니 다.그리고 A 의 looper 는 자동 으로 공유 메시지 대기 열 에서 메 시 지 를 꺼 내 처리 합 니 다.반대로
하위 스 레 드 가 주 스 레 드 에 메 시 지 를 보 냅 니 다.
서브 스 레 드 간 통신
2.위 는 하위 스 레 드 에서 메 인 스 레 드 가 제공 하 는 Handler 를 이용 하여 메 시 지 를 보 낸 다음 에 메 인 스 레 드 의 Looper 가 메시지 대기 열 에서 가 져 와 처리 합 니 다.그러면 또 다른 두 가지 상황 이 있다.
1.메 인 스 레 드 에서 하위 스 레 드 로 메 시 지 를 보 냅 니 다.
채택 한 방법 은 앞 과 유사 하 다.하위 스 레 드 에서 AHandler 를 예화 하고 메 시 지 를 처리 하 는 방법 을 설정 해 야 합 니 다.또한 하위 스 레 드 에 메시지 큐 와 Looper 의 폴 링 이 없 기 때문에 Looper.prepare(),Looper.loop()을 추가 하여 각각 메시지 큐 를 만 들 고 폴 링 을 시작 해 야 합 니 다.그리고 메 인 스 레 드 에서 이 A Handler 를 사용 하여 메 시 지 를 보 내 면 됩 니 다.
2.서브 스 레 드 A 와 서브 스 레 드 B 간 의 통신.
3.Handler 안에 실 용적 인 API 가 있 습 니까?
기억 하 세 요:
Handler 는 단순히 메시지 큐 에 메 시 지 를 보 내 거나 post 방식 을 사용 합 니 다.
UI 스 레 드 와 통신 하 는 데 도움 이 되 는 더 편리 한 방법 이 있 습 니 다.
만약 당신 이 지금 Handler 의 API 를 본다 면,이 몇 가지 방법 을 똑똑히 볼 수 있 습 니 다.
이곳 의 코드 는 모두 매우 기본 적 인 것 이지 만,너 는 주석 을 잘 볼 수 있다.
예시 1:Handler 의"post"방법 사용 하기
public class TestActivity extends Activity {
// ...
// all standard stuff
@Override
public void onCreate(Bundle savedInstanceState) {
// ...
// all standard stuff
// we're creating a new handler here
// and we're in the UI Thread (default)
// so this Handler is associated with the UI thread
Handler mHandler = new Handler();
// I want to start doing something really long
// which means I should run the fella in another thread.
// I do that by sending a message - in the form of another runnable object
// But first, I'm going to create a Runnable object or a message for this
Runnable mRunnableOnSeparateThread = new Runnable() {
@Override
public void run () {
// do some long operation
longOperation();
// After mRunnableOnSeparateThread is done with it's job,
// I need to tell the user that i'm done
// which means I need to send a message back to the UI thread
// who do we know that's associated with the UI thread?
mHandler.post(new Runnable(){
@Override
public void run(){
// do some UI related thing
// like update a progress bar or TextView
// ....
}
});
}
};
// Cool but I've not executed the mRunnableOnSeparateThread yet
// I've only defined the message to be sent
// When I execute it though, I want it to be in a different thread
// that was the whole point.
new Thread(mRunnableOnSeparateThread).start();
}
}
Handler 대상 이 아예 없다 면,post 방법 을 바 꾸 는 것 은 어 려 울 것 이다.예시 2:postDelayed 방법 사용 하기
최근 에 본 사이트 에서 새로 소개 한 기능 에서 저 는 매번 EditText 의 자동 완성 기능 을 모 의 해 야 합 니 다.문자 가 바 뀔 때마다 API 호출 을 실행 하여 서버 에서 데 이 터 를 검색 합 니 다.
앱 이 API 를 호출 하 는 횟수 를 줄 이 고 싶 어 Handler 의 postDelayed 방법 으로 이 기능 을 구현 하기 로 했다.
이 예 는 평행 처 리 를 대상 으로 하지 않 고 Handler 가 메시지 대기 열 에 메 시 지 를 보 내 고 메 시 지 를 미래의 어느 한 지점 에서 실행 하도록 배정 하 는 등 이다.
// the below code is inside a TextWatcher
// which implements the onTextChanged method
// I've simplified it to only highlight the parts we're
// interested in
private long lastChange = 0;
@Override
public void onTextChanged(final CharSequence chars,
int start, int before, int count) {
// The handler is spawned from the UI thread
new Handler().postDelayed(
// argument 1 for postDelated = message to be sent
new Runnable() {
@Override
public void run() {
if (noChangeInText_InTheLastFewSeconds()) {
searchAndPopulateListView(chars.toString());
// logic
}
}
},
// argument 2 for postDelated = delay before execution
300);
lastChange = System.currentTimeMillis();
}
private boolean noChangeInText_InTheLastFewSeconds() {
return System.currentTimeMillis() - lastChange >= 300
}
마지막 으로 저 는'post AtTime'이라는 방법 을 독자 들 에 게 연락 으로 남 겼 습 니 다.Handler 를 파악 하 셨 나 요?그렇다면 스 레 드 를 마음껏 사용 할 수 있 습 니 다.이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
⚙️ 안드로이드 Thread와 Handler 2앞서 말씀드린 Message 정보들은 Message의 public 변수로 설명할 수 있습니다. 구현된 Runnable은, 해당 Runnable을 사용하는 스레드에서, 구현된 run()의 정의대로 실행됩니다. 즉, 스...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.