[TOC]
# 概要

## AIDL
### 使用方法
服務端:1.創建接口,2.定義binder,實現接口,3.創建服務,返回binder;
客戶端:1.綁定服務,2.實現ServiceConnection綁定監聽,3.在綁定成功的回調中,將IBinder轉換成AIDL的接口代理對象。
客戶端和服務端綁定成功后,就可以通過AIDL的接口代理對象,就像直接調用本地方法一樣,調用服務端的方法了。需要注意的是,AIDL間傳遞的對象要實現Parcelable接口。
### 綁定過程
客戶端先調用bindService方法,發起綁定服務的請求,通過ServiceManager,拿到ActivityManagerService,也就是AMS,然后通過AMS向服務端發起bindService的請求。然后服務端接收到綁定請求,以Handler消息機制的方式,發送一個綁定服務的Message,然后在ActivityThread中處理這個綁定請求,調用onBind函數,并返回對應的IBinder對象。這個返回IBinder對象的操作,基本就和綁定過程的通過ServiceManager、AMS類似了。
### AIDL和Binder的關系
AIDL的使用實質就是對Binder機制的封裝,主要就是將Binder封裝成一個代理對象proxy,從用戶的角度看,就像是客戶端直接調用了服務端的代碼。
## oneway
### 主要有兩個特性:
oneway 主要有兩個特性:異步調用和串行化處理。異步調用是指應用向 binder 驅動發送數據后不需要掛起線程等待 binder 驅動的回復,而是直接結束。像一些系統服務調用應用進程的時候就會使用 oneway,比如 AMS 調用應用進程啟動 Activity,這樣就算應用進程中做了耗時的任務,也不會阻塞系統服務的運行。
### binder 協議
非oneway

如果是 oneway 的話,客戶端就不需要掛起線程等待:

涉及到的 binder 命令也有規律,由外部發送給 binder 驅動的都是 BC\_ 開頭,由 binder 驅動發往外部的都是 BR\_開頭。
### 怎么理解客戶端線程掛起等待呢?有沒有實際占用 CPU 的調度?
這里的掛起相當于 Thread 的 sleep,是真正的"休眠",底層調用的是 waiteventinterruptible() Linux 系統函數。
### waiteventinterruptible函數
Handle 中最關鍵的地方就是 Looper 的阻塞與喚醒,阻塞是調用了 nativePollOnce() 方法,當時對它的底層實現感興趣,就去了解了一下,也學習到 Linux 用來實現阻塞/喚醒的 select、poll 和 epoll 機制
## Intent 直接傳 Bitmap
Bitmap 太大會拋 TransactionTooLargeException 異常,原因是:底層判斷只要 Binder Transaction 失敗,且 Intent 的數據大于 200k 就會拋這個異常了。(見:android\_util\_Binder.cpp 文件 signalExceptionForError 方法)
### Intent 傳值會有大小限制。
應用進程在啟動 Binder 機制時會映射一塊 1M 大小的內存,所有正在進行的 Binder 事務共享這 1M 的緩沖區 。當使用 Intent 進行 IPC 時申請的緩存超過 1M - 其他事務占用的內存時,就會申請失敗拋 TransactionTooLargeException 異常了
### 繞開這個限制呢?
通過 AIDL 使用 Binder 進行 IPC 就不受這個限制,具體代碼如下:
```
Bundle bundle = new Bundle();
bundle.putBinder("binder", new IRemoteGetBitmap.Stub() {
@Override public Bitmap getBitMap() throws RemoteException { return mBitmap; } }); intent.putExtras(bundle);
```
### 總結
較大的 bitmap 直接通過 Intent 傳遞容易拋異常是因為 Intent 啟動組件時,系統禁掉了文件描述符 fd 機制 , bitmap 無法利用共享內存,只能拷貝到 Binder 映射的緩沖區,導致緩沖區超限, 觸發異常; 而通過 putBinder 的方式,避免了 Intent 禁用描述符的影響,bitmap 寫 parcel 時的 allowFds 默認是 true , 可以利用共享內存,所以能高效傳輸圖片。
# 參考資料
[Android 深入淺出AIDL(二)](https://blog.csdn.net/qian520ao/article/details/78074983)
[看你簡歷上寫熟悉 AIDL,說一說 oneway 吧](https://juejin.cn/post/6844904147947356173)
[Android Binder 原理分析](https://juejin.cn/post/6874616109266370568)
[跨進程傳遞大圖,你能想到哪些方案呢?](https://juejin.cn/post/6844904182126739470)
- Android
- 四大組件
- Activity
- Fragment
- Service
- 序列化
- Handler
- Hander介紹
- MessageQueue詳細
- 啟動流程
- 系統啟動流程
- 應用啟動流程
- Activity啟動流程
- View
- view繪制
- view事件傳遞
- choreographer
- LayoutInflater
- UI渲染概念
- Binder
- Binder原理
- Binder最大數據
- Binder小結
- Android組件
- ListView原理
- RecyclerView原理
- SharePreferences
- AsyncTask
- Sqlite
- SQLCipher加密
- 遷移與修復
- Sqlite內核
- Sqlite優化v2
- sqlite索引
- sqlite之wal
- sqlite之鎖機制
- 網絡
- 基礎
- TCP
- HTTP
- HTTP1.1
- HTTP2.0
- HTTPS
- HTTP3.0
- HTTP進化圖
- HTTP小結
- 實踐
- 網絡優化
- Json
- ProtoBuffer
- 斷點續傳
- 性能
- 卡頓
- 卡頓監控
- ANR
- ANR監控
- 內存
- 內存問題與優化
- 圖片內存優化
- 線下內存監控
- 線上內存監控
- 啟動優化
- 死鎖監控
- 崩潰監控
- 包體積優化
- UI渲染優化
- UI常規優化
- I/O監控
- 電量監控
- 第三方框架
- 網絡框架
- Volley
- Okhttp
- 網絡框架n問
- OkHttp原理N問
- 設計模式
- EventBus
- Rxjava
- 圖片
- ImageWoker
- Gilde的優化
- APT
- 依賴注入
- APT
- ARouter
- ButterKnife
- MMKV
- Jetpack
- 協程
- MVI
- Startup
- DataBinder
- 黑科技
- hook
- 運行期Java-hook技術
- 編譯期hook
- ASM
- Transform增量編譯
- 運行期Native-hook技術
- 熱修復
- 插件化
- AAB
- Shadow
- 虛擬機
- 其他
- UI自動化
- JavaParser
- Android Line
- 編譯
- 疑難雜癥
- Android11滑動異常
- 方案
- 工業化
- 模塊化
- 隱私合規
- 動態化
- 項目管理
- 業務啟動優化
- 業務架構設計
- 性能優化case
- 性能優化-排查思路
- 性能優化-現有方案
- 登錄
- 搜索
- C++
- NDK入門
- 跨平臺
- H5
- Flutter
- Flutter 性能優化
- 數據跨平臺