Android 메시지 큐 모델 상세 설명 및 인 스 턴 스

5752 단어 Android메시지 큐
Android 메시지 큐 모델 상세 설명 및 인 스 턴 스
Android 시스템 의 메시지 큐 와 메시지 순환 은 모두 구체 적 인 스 레 드 를 대상 으로 합 니 다.하나의 스 레 드 가 존재 할 수 있 습 니 다(물론 존재 하지 않 을 수도 있 습 니 다)하나의 메시지 큐(Message Queue)와 하나의 메시지 순환(Looper).Android 에서 UI 스 레 드(메 인 스 레 드)를 제외 하고 만 든 작업 스 레 드 는 기본적으로 메시지 순환 과 메시지 큐 가 없습니다.이 스 레 드 가 메시지 큐 와 메시지 순환 을 가지 고 메시지 처리 체 제 를 갖 추 려 면 스 레 드 에서 먼저 Looper.prepare()를 호출 하여 메시지 큐 를 만 든 다음 Looper.loop()을 호출 하여 메시지 순환 에 들 어가 야 합 니 다.다음 코드 와 같이:

class LooperThread extends Thread { 
  public Handler mHandler; 
 
  public void run() { 
   Looper.prepare(); 
 
   mHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     // process incoming messages here 
    } 
   }; 
 
   Looper.loop(); 
  } 
 } 
      이렇게 하면 이 라인 은 정보 처리 메커니즘 을 갖 추 게 된다.Looper.prepare()를 호출 하지 않 고 메시지 대기 열 을 만 들 면"Java.lang.Runtime Exception:Can't create handler inside thread that has not called Looper.prepare()"의 오류 가 발생 합 니 다. 
       아래 그림 을 통 해 UI Thread,Worker Thread,Handler,Massage Queue,Looper 간 의 관 계 를 뚜렷하게 나 타 낼 수 있 습 니 다.
 
       위의 그림 속 의 몇 가지 기본 개념 을 설명 하 다. 
       1.Message
       메시지 대상 은 말 그대로 메시지 정 보 를 기록 하 는 유형 이다.이 종 류 는 몇 가지 비교적 중요 한 필드 가 있다.
       a.arg 1 과 arg 2:우 리 는 우리 가 전달 해 야 할 정형 값 을 두 필드 로 저장 할 수 있 습 니 다.Service 에서 우 리 는 Service 의 ID 를 저장 할 수 있 습 니 다.
       b.obj:이 필드 는 Object 형식 입 니 다.우 리 는 이 필드 에서 여러 가지 메 시 지 를 받 는 사람 에 게 전달 할 수 있 습 니 다.
       c.what:이 필드 는 메시지 의 표지 라 고 할 수 있 습 니 다.메시지 처리 에서 우 리 는 이 필드 의 서로 다른 값 에 따라 서로 다른 처 리 를 할 수 있 습 니 다.예 를 들 어 우리 가 Button 사건 을 처리 할 때 switch(v.getId()를 통 해 어떤 단 추 를 눌 렀 는 지 판단 할 수 있 습 니 다.
       Message 를 사용 할 때 new Message()를 통 해 Message 인 스 턴 스 를 만 들 수 있 지만 Android 는 Message.obtain()이나 Handler.obtainMessage()를 통 해 Message 대상 을 가 져 오 는 것 을 추천 합 니 다.이것 은 반드시 새로운 인 스 턴 스 를 직접 만 드 는 것 이 아니 라 메시지 풀 에서 사용 가능 한 Message 인 스 턴 스 가 있 는 지 확인 하고 존재 하면 이 인 스 턴 스 를 직접 꺼 내 서 되 돌려 줍 니 다.반면 메시지 풀 에 사용 가능 한 Message 인 스 턴 스 가 없 으 면 주어진 매개 변수 new 에 따라 새 Message 대상 을 만 듭 니 다.소스 코드 분석 을 통 해 알 수 있 듯 이 안 드 로 이 드 시스템 은 기본 적 인 상황 에서 메시지 풀 에서 10 개의 Message 대상 을 예화 했다. 
       2.MessageQueue
       메시지 큐 는 Message 대상 의 데이터 구 조 를 저장 하고'선진 선 출'원칙 에 따라 메 시 지 를 저장 합 니 다.저장 은 실제 의미 의 저장 이 아니 라 Message 대상 을 링크 로 연결 합 니 다.Message Queue 대상 은 우리 가 만 들 필요 가 없 이 Looper 대상 이 관리 합 니 다.하나의 스 레 드 는 최대 하나의 Message Queue 만 가 질 수 있 습 니 다.현재 스 레 드 에 있 는 Message Queue 를 Looper.my Queue()를 통 해 가 져 올 수 있 습 니 다. 
       3.Looper
       Message Queue 의 관리 자 는 한 스 레 드 에 Looper 대상 이 존재 하면 Message Queue 대상 이 존재 하고 하나의 Looper 대상 과 하나의 Message Queue 대상 만 존재 합 니 다.만약 에 저희 스 레 드 에 Looper 대상 이 존재 한다 면 저 희 는 Looper.my Looper()를 통 해 얻 을 수 있 습 니 다.또한 저 희 는 Looper.getMainLooper()를 통 해 현재 응용 시스템 의 메 인 스 레 드 의 Looper 대상 을 얻 을 수 있 습 니 다.이 곳 에서 주의 할 점 이 있 습 니 다.만약 에 Looper 대상 이 응용 프로그램의 메 인 스 레 드 에 있다 면 Looper.my Looper()와 Looper.getMainLooper()는 같은 대상 을 가 져 옵 니 다. 
       4.Handler
       메시지 의 처리 자.Handler 대상 을 통 해 메시지 대상 을 봉인 한 다음 sendmessage(msg)를 통 해 메시지 대상 을 메시지 큐 에 추가 할 수 있 습 니 다.Message Queue 가 이 Message 로 순환 할 때 이 Message 대상 에 대응 하 는 handler 대상 의 handle Message()방법 으로 처리 합 니 다.handleMessage()방법 에서 메 시 지 를 처리 하기 때문에 Handler 에서 계승 하 는 클래스 를 만 들 고 handleMessage()에서 우리 가 필요 로 하 는 작업 을 처리 해 야 합 니 다. 
       또한,Android UI 작업 은 스 레 드 가 안전 하지 않 기 때문에 하위 스 레 드 에서 UI 를 업데이트 할 수 없다 는 것 을 알 고 있 습 니 다.그러나 Andriod 는 몇 가지 방법 을 제공 하여 하위 스 레 드 에서 UI 스 레 드 업데이트 인터페이스 에 알 릴 수 있 습 니 다. 
  • Activity.runOnUiThread( Runnable )
  • View.post( Runnable )
  • View.postDelayed( Runnable, long )
  • Handler
  •        Handler 를 통 해 하위 스 레 드 에서 보 낸 데 이 터 를 Handler 로 받 고 이 데이터 로 메 인 스 레 드 에 맞 춰 UI 를 업데이트 하 는 것 이 자주 사용 된다.그러면 메 인 스 레 드 에 Handler 대상 을 만 들 고,하위 스 레 드 에서 Handler 의 sendmessage 방법 을 호출 하면 메 인 스 레 드 메시지 큐 에 메 시 지 를 넣 고,Handler 메 인 스 레 드 에서 이 handler 의 handleMessage 방법 으로 메 시 지 를 처리 합 니 다.  
    
    package com.superonion; 
     
    import android.app.Activity; 
    import android.os.Bundle; 
    import android.os.Message; 
    import android.util.Log; 
    import android.os.Handler; 
     
    public class MyHandler extends Activity { 
      static final String TAG = "Handler"; 
      Handler h = new Handler(){ 
        public void handleMessage (Message msg) 
        { 
          switch(msg.what) 
          { 
          case HANDLER_TEST: 
            Log.d(TAG, "The handler thread id = " + Thread.currentThread().getId() + "
    "); break; } } }; static final int HANDLER_TEST = 1; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "The main thread id = " + Thread.currentThread().getId() + "
    "); new myThread().start(); setContentView(R.layout.main); } class myThread extends Thread { public void run() { Message msg = new Message(); msg.what = HANDLER_TEST; h.sendMessage(msg); Log.d(TAG, "The worker thread id = " + Thread.currentThread().getId() + "
    "); } } }
            상기 코드 에서 Handler 가 메 인 스 레 드 에 생 성 된 후 하위 스 레 드 는 sendmessage()방법 을 통 해 메 시 지 를 메 인 스 레 드 에 보 내 고 handleMessage()방법 에서 처리 할 수 있 습 니 다.
     읽 어 주 셔 서 감사합니다. 여러분 을 도 울 수 있 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

    좋은 웹페이지 즐겨찾기