Handler的sendMessage和post的區(qū)別

我們常常使用Handler來(lái)更新UI,但是很多同學(xué)對(duì)Handler的sendMessage和post的區(qū)別不是很了解,我們先看使用方式的區(qū)別:

sendMessage的用法:

public class MainActivity extends AppCompatActivity {
private TextView mTextView;
private String new_str = "";
//實(shí)例化Handler,重寫(xiě)回調(diào)方法
Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
        if (msg.what == 0) {
            /*sendMessage方法更新UI的操作必須在handler的handleMessage回調(diào)中完成*/
            mTextView.setText(new_str);
        }
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    new Thread(new Runnable() {
        @Override
        public void run() {
            new_str = "sendMessage更新UI";
            /*sendMessage方法解決UI更新發(fā)送消息給handler(主線(xiàn)程中的handler)*/
            mHandler.sendEmptyMessage(0);
        }
    }).start();
}                                     

post的用法:

public class MainActivity extends AppCompatActivity {
private TextView mTextView;
private String new_str = "";
//實(shí)例化Handler
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //這里調(diào)用了post方法,和sendMessage一樣達(dá)到了更新UI的目的
     mHandler.post(new Runnable() {
            @Override
            public void run() {
                mTextView.setText(new_str);
            }
        });
    }
}).start();
}

上面的兩種用法都是很常見(jiàn)的(這里未考慮內(nèi)存泄漏,重點(diǎn)只關(guān)注Handler的使用),使用這兩種方法都能夠?qū)崿F(xiàn)UI的更新,那么post和sendMessage有什么區(qū)別呢,我們要跟蹤源碼來(lái)看看post到底做了什么。

handler中post的源碼:

public final boolean post(Runnable r)
{
   return  sendMessageDelayed(getPostMessage(r), 0);
}
//獲得了message實(shí)例,將r賦給callback,接下來(lái)還是和sendMessage一致的操作,進(jìn)入sendMessageDelayed
 private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

最終還是到sendMessageAtTime這個(gè)方法里面

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    if (queue == null) {
        RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
        Log.w("Looper", e.getMessage(), e);
        return false;
    }
    return enqueueMessage(queue, msg, uptimeMillis);
}

所以可以知道,handler.post和handler.sendMessage本質(zhì)上是沒(méi)有區(qū)別的,都是發(fā)送一個(gè)消息到消息隊(duì)列中,只不過(guò)post使用方式更簡(jiǎn)單。
在handler的出隊(duì)列方式中,可以看到如何進(jìn)入不同的回調(diào)

消息出隊(duì)列源碼

 /**
 * Handle system messages here.
 */
   public void dispatchMessage(Message msg) {
  //如果是post,callback不為空,直接進(jìn)入handleCallback
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
   //如果是sendMessage,且創(chuàng)建handler時(shí)沒(méi)有傳入callback,則callback為空,直接進(jìn)入handleMessage,也就是我們自己復(fù)寫(xiě)的處理Message的方法
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}

//直接run并不會(huì)啟動(dòng)新線(xiàn)程,所以這就是post的runnable里面可以直接更新UI的原因
   private static void handleCallback(Message message) {
    message.callback.run();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容