鏈接:https://www.zhihu.com/question/44329366/answer/97794649
1. 關于**Binder**,可以先看看我之前的回答,[為什么 Android 要采用 Binder 作為 IPC 機制? - Gityuan 的回答](https://www.zhihu.com/question/39440766/answer/89210950)
2. 關于**Handler**為何不采用Binder, 先總結說一句,Handler完全可以通過BInder,但是殺雞焉用牛刀。 后面再補充...
*****
如果僅僅從上層來看待這個問題,那是盲人摸象。這個問題需要從上往下追溯才能看清本原,重頭戲也在底層,這里的底層不僅僅是Native層,還需要對Linux所有了解,才能真正理解透徹。看到前面大家的回答,我覺得有必要盡早回復一下,以免有些回答者誤導更多新人。
**1**、有人說管道是Linux IPC機制,IPC英文全稱Inter-Process Communication,意思是進程間通信,而Handler是用于同一進程內的線程間通信,怎么會用到管道呢?這樣的回答應該是看了一些教科書,但并沒有真正理解透徹,這是不對的。**Handler底層的確是采用管道機制。**
先簡單說說管道,其本質是也是文件,但又和普通的文件會有所不同:管道緩沖區大小一般為1頁,即4K字節。管道分為讀端和寫端,讀端負責從管道拿數據,當數據為空時則阻塞;寫端向管道寫數據,當管道緩存區滿時則阻塞。
**2**、再說說Handler是如何使用管道的
有人說Handler所涉及的MessageQueue/Message/Looper/Handler這4個類都是采用Java實現,哪來的底層采用管道的機會?這是不對的
在Looper.loop方法,會不斷循環處理Message,其中消息的獲取是通過
~~~jsp
Message msg = queue.next(); //用于獲取消息隊列中的下一條消息
~~~
該方法中會調用nativePollOnce()方法,這便是一個native方法,再通過JNI調用進入Native層,便采用了管道,比如epoll\_create/epoll\_wait/epoll\_ctl,這里通過一副圖來讓大家看清楚Java層與native的聯系。

流程就不細說了,直接去看代碼或者我的博客 [Android消息機制2-Handler(Native層)](https://link.zhihu.com/?target=http%3A//gityuan.com/2015/12/27/handler-message-native/%23nativewake)。
**(3)**到這里有人可能好奇,既然是同一個進程間的線程通信,為何需要管道呢?
線程之間內存共享,通過Handler通信,消息池的內容并不需要從一個線程拷貝到另一個線程,
因為兩線程可使用的內存時同一個區域,都有權直接訪問,當然也存在線程私有區域ThreadLocal(這里不涉及)。即然不需要拷貝內存,那管道是何作用呢?
**Handler機制中管道作用**就是當一個線程A準備好Message,并放入消息池,這時需要通知另一個線程B去處理這個消息。線程A向管道的寫端寫入數據1(對于老的Android版本是寫入字符`W`),管道有數據便會喚醒線程B去處理消息。管道主要工作是用于通知另一個線程的,這便是最核心的作用。
**(4)**有了這些關于Handler的準備,再加上[為什么 Android 要采用 Binder 作為 IPC 機制? - Gityuan 的回答](https://www.zhihu.com/question/39440766/answer/89210950),再來說說handler為何采用管道而非Binder?
handler不采用Binder,并非binder完成不了這個功能,而是太浪費CPU和內存資源了。
Binder采用C/S架構,往往用于不同進程間的通信
* 從內存角度:通信過程中還涉及一次內存拷貝,handler機制中的Message根本不需要拷貝,本身就是在同一個內存。Handler需要的僅僅是告訴另一個線程數據有了。
* 從CPU角度,為了Binder通信底層驅動還需要為何一個binder線程池,每次通信涉及binder線程的創建和內存分配等比較浪費CPU資源。
Handler不宜采用Binder,殺雞焉用牛刀。
**(5)**Binder Vs Handler
Binder用于進程間通信,而Handler消息機制用于同進程的線程間通信。
* 有人可能會疑惑,為何Binder/Socket用于進程間通信,能否用于線程間通信呢?答案是肯定,對于兩個具有獨立地址空間的進程通信都可以,當然也能用于共享內存空間的兩個線程間通信,這就好比殺雞用牛刀。
* 接著可能還有人會疑惑,那handler消息機制能否用于進程間通信?答案是不能,Handler只能用于共享內存地址空間的兩個線程間通信,即同進程的兩個線程間通信。
- 前言
- Android系統的體系結構
- Dalvik VM 和 JVM 的比較
- Android 打包應用程序并安裝的過程
- Android ADB工具
- Android應用開發
- Android UI相關知識總結
- Android 中window 、view、 Activity的關系
- Android應用界面
- Android中的drawable和bitmap
- AndroidUI組件adapterView及其子類和Adapter的關系
- Android四大組件
- Android 數據存儲
- SharedPreference
- Android應用的資源
- 數組資源
- 使用Drawable資源
- Material Design
- Android 進程和線程
- 進程
- 線程
- Android Application類的介紹
- 意圖(Intent)
- Intent 和 Intent 過濾器(Google官網介紹)
- Android中關于任務棧的總結
- 任務和返回棧(官網譯文)
- 總結
- Android應用安全現狀與解決方案
- Android 安全開發
- HTTPS
- 安卓 代碼混淆與打包
- 動態注入技術(hook技術)
- 一、什么是hook技術
- 二、常用的Hook 工具
- Xposed源碼剖析——概述
- Xposed源碼剖析——app_process作用詳解
- Xposed源碼剖析——Xposed初始化
- Xposed源碼剖析——hook具體實現
- 無需Root也能Hook?——Depoxsed框架演示
- 三、HookAndroid應用
- 四、Hook原生應用程序
- 五、Hook 檢測/修復
- Android 應用的逆向與加固保護技術
- OpenCV在Android中的開發
- Android高級開發進階
- 高級UI
- UI繪制流程及原理
- Android新布局ConstraintLayout約束布局
- 關鍵幀動畫
- 幀動畫共享元素變換
- Android異步消息處理機制完全解析,帶你從源碼的角度徹底理解
- Android中為什么主線程不會因為Looper.loop()里的死循環卡死?
- 為什么 Android 要采用 Binder 作為 IPC 機制?
- JVM 中一個線程的 Java 棧和寄存器中分別放的是什么?
- Android源碼的Binder權限是如何控制?
- 如何詳解 Activity 的生命周期?
- 為什么Android的Handler采用管道而不使用Binder?
- ThreadLocal,你真的懂了嗎?
- Android屏幕刷新機制