<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                當一切準備就緒后,Java層的消息循環處理,也就是Looper會在一個循環中提取并處理消息。消息的提取就是調用MessageQueue的next()方法。當消息隊列為空時,next就會阻塞。MessageQueue同時支持Java層和Native層的事件,那么其next()方法該怎么實現呢?具體代碼如下: **MessagQueue.java-->MessageQueue.next()** ``` final Message next() { int pendingIdleHandlerCount = -1; int nextPollTimeoutMillis = 0; for (;;) { ...... // mPtr保存了NativeMessageQueue的指針,調用nativePollOnce進行等待 nativePollOnce(mPtr,nextPollTimeoutMillis); synchronized (this) { final long now = SystemClock.uptimeMillis(); // mMessages用來存儲消息,這里從其中取一個消息進行處理 final Message msg = mMessages; if (msg != null) { final long when = msg.when; if (now >= when) { mBlocked = false; mMessages = msg.next; msg.next = null; msg.markInUse(); return msg; // 返回一個Message給Looper進行派發和處理 } else { nextPollTimeoutMillis = (int) Math.min(when- now, Integer.MAX_VALUE); } } else { nextPollTimeoutMillis = -1; } ...... /* 處理注冊的IdleHandler,當MessageQueue中沒有Message時, Looper會調用IdleHandler做一些工作,例如做垃圾回收等 */ ...... pendingIdleHandlerCount = 0; nextPollTimeoutMillis = 0; } } } ``` 看到這里,可能會有人覺得這個MessageQueue很簡單,不就是從以前在Java層的wait變成現在Native層的wait了嗎?但是事情本質比表象要復雜得多,來思考下面的情況: nativePollOnce()返回后,next()方法將從mMessages中提取一個消息。也就是說,要讓nativePollOnce()返回,至少要添加一個消息到消息隊列,否則nativePollOnce()不過是做了一次無用功罷了。 如果nativePollOnce()將在Native層等待,就表明Native層也可以投遞Message,但是從Message類的實現代碼上看,該類和Native層沒有建立任何關系。那么nativePollOnce()在等待什么呢? 對于上面的問題,相信有些讀者心中已有了答案:nativePollOnce()不僅在等待Java層來的Message,實際上還在Native還做了大量的工作。 下面我們來分析Java層投遞Message并觸發nativePollOnce工作的正常流程。 #### 1. 在Java層投遞Message MessageQueue的enqueueMessage函數完成將一個Message投遞到MessageQueue中的工作,其代碼如下: **MesssageQueue.java-->MessageQueue.enqueueMessage()** ``` final boolean enqueueMessage(Message msg, longwhen) { ...... finalboolean needWake; synchronized (this) { if(mQuiting) { return false; }else if (msg.target == null) { mQuiting = true; } msg.when = when; Message p = mMessages; if(p == null || when == 0 || when < p.when) { /* 如果p為空,表明消息隊列中沒有消息,那么msg將是第一個消息,needWake 需要根據mBlocked的情況考慮是否觸發 */ msg.next= p; mMessages = msg; needWake = mBlocked; } else { // 如果p不為空,表明消息隊列中還有剩余消息,需要將新的msg加到消息尾 Message prev = null; while (p != null && p.when <= when) { prev = p; p = p.next; } msg.next = prev.next; prev.next = msg; // 因為消息隊列之前還剩余有消息,所以這里不用調用nativeWakeup needWake = false; } } if(needWake) { // 調用nativeWake,以觸發nativePollOnce函數結束等待 nativeWake(mPtr); } returntrue; } ``` 上面的代碼比較簡單,主要功能是: - 將message按執行時間排序,并加入消息隊。 - 根據情況調用nativeWake函數,以觸發nativePollOnce函數,結束等待。 * * * * * **建議** 雖然代碼簡單,但是對于那些不熟悉多線程的讀者,還是要細細品味一下mBlocked值的作用。我們常說細節體現美,代碼也一樣,這個小小的mBlocked正是如此。 * * * * * #### 2. nativeWake函數分析 nativeWake函數的代碼如下所示: **android_os_MessageQueue.cpp-->android_os_MessageQueue_nativeWake()** ``` static voidandroid_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint ptr) { NativeMessageQueue* nativeMessageQueue = // 取出NativeMessageQueue對象 reinterpret_cast<NativeMessageQueue*>(ptr); returnnativeMessageQueue->wake(); // 調用它的wake函數 } [android_os_MessageQueue.cpp-->NativeMessageQueue::wake()] void NativeMessageQueue::wake() { mLooper->wake(); // 層層調用,現在轉到mLooper的wake函數 } ``` Native Looper的wake函數代碼如下: **Looper.cpp-->Looper::wake()** ``` void Looper::wake() { ssize_tnWrite; do { // 向管道的寫端寫入一個字符 nWrite = write(mWakeWritePipeFd, "W", 1); } while(nWrite == -1 && errno == EINTR); } ``` Wake()函數則更為簡單,僅僅向管道的寫端寫入一個字符”W”,這樣管道的讀端就會因為有數據可讀而從等待狀態中醒來。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看