Handler 총화

6989 단어
  • 기본 적 인 개념 을 봅 시다
  • messagequue = = = 중국어 번역 은 메시지 큐 입 니 다. 내부 에 메 시 지 를 저장 하고 큐 형식 으로 대외 적 으로 증가 와 삭제 방법 을 제공 합 니 다. 그러나 그의 내 부 는 큐 의 구조 형식 이 아니 라 단일 링크 의 데이터 구조 로 메시지 목록 을 저장 합 니 다
  • .
  • looper = = 폴 더 는 메시지 순환 으로 도 이해 할 수 있 습 니 다. messagequue 는 메시지 용기 이기 때문에 그 는 끊임없이 교대 훈련 정 보 를 책임 지고 메시지 처리 가 있 으 면 메 시 지 를 처리 합 니 다. 그렇지 않 으 면 계속 기다 리 고 있 습 니 다.그 는 스 레 드 가 아 닌 특수 한 개념 threadlocal 도 가지 고 있다. 그의 역할 은 모든 스 레 드 에 데 이 터 를 저장 하고 현재 스 레 드 를 연결 하 는 loop
  • 을 책임 지 는 것 이다.
  • 우선 우 리 는 handel
  • 을 만 드 는 것 을 알 고 있다.
    
        new Handler();              ?
    
         public Handler(Callback callback, boolean async) {
    
                if (FIND_POTENTIAL_LEAKS) {
    
                    final Class extends Handler> klass = getClass();
    
                    if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
    
                            (klass.getModifiers() & Modifier.STATIC) == 0) {
    
                        Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
    
                            klass.getCanonicalName());
    
                    }
    
                //  loper  ,  lopper         ,                      Looper.prepare();
    
                mLooper = Looper.myLooper();
    
                if (mLooper == null) {
    
                    throw new RuntimeException(
    
                        "Can't create handler inside thread that has not called Looper.prepare()");
    
                }
    
                mQueue = mLooper.mQueue;
    
                mCallback = callback;
    
                mAsynchronous = async;
    
            }
    
            
    
               Looper.prepare();       ,  sThreadLocal           Looper  
    
            private static void prepare(boolean quitAllowed) {
    
            if (sThreadLocal.get() != null) {
    
                throw new RuntimeException("Only one Looper may be created per thread");
    
            }
    
            sThreadLocal.set(new Looper(quitAllowed));
    
        }
    
        
    
                            !
    
              activitythred         Looper.prepareMainLooper()   Looper.prepare()  ,                    Looper  ,           Looper.prepare()   。
    
    
  • 그리고 저희 가 메 시 지 를 보 내 려 면 무엇이 필요 합 니까?
      messag message,          message,    message     ,2 ,          Message.obtain();              !
    
      //      ,     Message          ,          ,      ,           。
    
      `  public static Message obtain() {
    
      synchronized (sPoolSync) {
    
          if (sPool != null) {
    
              Message m = sPool;
    
              sPool = m.next;
    
              m.next = null;
    
              m.flags = 0; // clear in-use flag
    
              sPoolSize--;
    
              return m;
    
          }
    
      }
    
      return new Message();
    
    }`
  • 소식 이 있 으 면 보 내 드 리 겠 습 니 다. 어떻게 보 내 드릴 까요?
  •     `handler.sendMessage(message);`,              。             ,               sendMessageAtTime(),      
    
    
        //  msg         Message  , uptimeMillis            ,                          
    
         public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    
            //  quer          
    
            MessageQueue queue = mQueue;
    
            if (queue == null) {
    
                RuntimeException e = new RuntimeException(
    
                        this + " sendMessageAtTime() called with no mQueue");
    
                Log.w("Looper", e.getMessage(), e);
    
                return false;
    
            }
    
            //  enqueueMessage
    
            return enqueueMessage(queue, msg, uptimeMillis);
    
        }
    
        //         ,MessageQueue    looper      ,    Looper       MessageQueue。
    
        private Looper(boolean quitAllowed) {
    
            mQueue = new MessageQueue(quitAllowed);
    
            mThread = Thread.currentThread();
    
        }
    
        
    
        
    
        
    
        
    
        
    
            enqueueMessage   ,          ,      messagequene
    
            final boolean enqueueMessage(Message msg, long when) {
    
            if (msg.when != 0) {
    
                throw new AndroidRuntimeException(msg + " This message is already in use.");
    
            }
    
            //        ,msg.target  handel
    
            if (msg.target == null && !mQuitAllowed) {
    
                throw new RuntimeException("Main thread not allowed to quit");
    
            }
    
            synchronized (this) {
    
                //     quit     true
    
                if (mQuiting) {
    
                    RuntimeException e = new RuntimeException(msg.target + " sending message to a Handler on a dead thread");
    
                    Log.w("MessageQueue", e.getMessage(), e);
    
                    return false;
    
                } else if (msg.target == null) {
    
                    mQuiting = true;
    
                }
    
                msg.when = when;
    
                Message p = mMessages;
    
                //               
    
                if (p == null || when == 0 || when < p.when) {
    
                    msg.next = p;
    
                    mMessages = msg;
    
                    this.notify();
    
                } else {
    
                    Message prev = null;
    
                    while (p != null && p.when <= when) {
    
                        prev = p;
    
                        p = p.next;
    
                    }
    
                    msg.next = prev.next;
    
                    prev.next = msg;
    
                    this.notify();
    
                }
    
            }
    
               if (needWake) {
    
                    // native        
    
                    nativeWake(mPtr);
    
                }
    
            return true;
    
        }
    
    
  • 다음은 소식 을 들 어 보 는 교대 훈련 loop. loop ()
  • 
        public static final void loop() {
    
        //  Looper
    
        Looper me = myLooper();
    
        MessageQueue queue = me.mQueue;
    
        while (true) {
    
            //                 MessageQueue   mMessages(      ),        ,          mMessages,           ,           。
          //MessageQueue  nex  ,                 ,                queue.next()
            null,      null,     mQuitting   ,        quit    
            Message msg = queue.next(); // might block
    
            if (msg != null) {
    
            //  handel         
    
                if (msg.target == null) {
    
                    return;
    
                }
    
                if (me.mLogging!= null) me.mLogging.println(
    
                        ">>>>> Dispatching to " + msg.target + " "
    
                        + msg.callback + ": " + msg.what
    
                        );
    
                //      handeld dispatchMessage       ,    msg.target handel        enqueueMessage        msg.target = this;         
    
                msg.target.dispatchMessage(msg);
    
                if (me.mLogging!= null) me.mLogging.println(
    
                        "<<<<< Finished to    " + msg.target + " "
    
                        + msg.callback);
    
                msg.recycle();
    
            }
    
        }
    
    }
    
    
    
    
    
    //         
    
    public void dispatchMessage(Message msg) {
    
        if (msg.callback != null) {
           //                          ,       handleMessage
            handleCallback(msg);
    
        } else {
    
            if (mCallback != null) {
    
                if (mCallback.handleMessage(msg)) {
    
                    return;
    
                }
    
            }
    
    
    
            handleMessage(msg);
    
        }
    
    }
    
    
    
    

    좋은 웹페이지 즐겨찾기