本章主要記錄一下自己在工作中,遇到車機多屏幕操作時CarUserService中的邏輯實現(xiàn)流程,所以啟動方面就簡單分析一下:
- 和汽車相關的服務主要依賴系統(tǒng)服務 CarServiceHelperService 開機時在 SystemServer 中啟動谣膳,如圖:
判斷是車,然后啟動服務 - 隨后通過類名加載類铅乡,并且通過反射構造服務類继谚,并且調(diào)用
startService
啟動如圖:
通過包路徑com.android.internal.car.CarServiceHelperService加載類
通過包路徑com.android.internal.car.CarServiceHelperService加載類
通過反射調(diào)用構造函數(shù) - 在
startService
方法中,將構造完成的對象添加到mServices
中隆判,并且調(diào)用onStart
,如圖:
startService(@NonNull final SystemService service) - 在 CarServiceHelperService 的
onStart
中會綁定一個包名為com.android.car
犬庇,action為android.car.ICar
的服務僧界,這就是系統(tǒng)中和汽車相關的核心服務 CarService ,如圖:
常量CAR_SERVICE_INTERFACE
綁定CarService - 綁定 CarService 的時候侨嘀,在 CarService 的
onCreate
方法中,構造了一個具體實現(xiàn)類mICarImpl
捂襟,并且在onBind
方法中返回mICarImpl
咬腕,如圖:
構造一個實現(xiàn)類
onBind返回實現(xiàn)類 - 在 ICarImpl 的構造方法中,新建了 CarUserService 和CarOccupantZoneService葬荷,CarUserService 是用來管理車載環(huán)境中多用戶操作涨共。而
CarOccupantZoneService 用來管理多用戶和座位的對應關系纽帖,這里我們只分析和顯示屏有關的,在車載環(huán)境中举反,可能有一個座位對應了一個顯示屏提供給用戶操作懊直,初始化的代碼如圖:
初始化CarUserService和CarOccupantZoneService - 在 ICarImpl 構造方法的最后,將所有構造完成的服務對象添加到成員變量
mAllServices
中火鼻。
添加到mAllServices - 在 ICarImpl 中室囊,
constructWithTrace
方法初始化了各個服務,它的邏輯是在調(diào)用對應類的構造方法之后魁索,把它加入到 CarLocalServices 的成員變量sLocalServiceObjects
中:
callable調(diào)用call,把返回的對象加入到一個ArrayMap中
將class作為key,進行了判重 - 隨后在 CarService 中調(diào)用了
init
方法融撞,初始化車載的各個服務,每一個子服務都實現(xiàn)了 CarServiceBase 的接口粗蔚,如圖:
各個服務類在構造完成之后調(diào)用init初始化
ICarImpl內(nèi)部是通過遍歷mAllServices尝偎,對每一個子服務調(diào)用init
CarServiceBase -
CarService 綁定成功之后,又到了 CarServiceHelperService 成員變量
mCarServiceConnection
的onServiceConnected
方法中鹏控,并且執(zhí)行handleCarServiceConnection
,如圖
image.png - 在
handleCarServiceConnection
方法中致扯,將mCarServiceBinder
指向iBinder
,至此 CarServiceHelperService 可以通過mCarServiceBinder
與 CarService 進行進程間通信牧挣;隨后調(diào)用了sendSetSystemServerConnectionsCall
方法急前,如圖:
mCarServiceBinder = iBinder - 在
sendSetSystemServerConnectionsCall
中,顧名思義瀑构,是將 CarServiceHelperService 的 Binder 發(fā)送給 CarService 裆针,code
取值是FIRST_CALL_TRANSACTION = 0x00000001
到LAST_CALL_TRANSACTION = 0x00ffffff
之間,這里之直接傳的FIRST_CALL_TRANSACTION
值為1,說明是aidl定義中為0的方法寺晌,如圖:
transact(0,null,Binder.FLAG_ONEWAY) -
sendSetSystemServerConnectionsCall
方法中binder
的具體實現(xiàn)類是 ICarImpl ,通過查看 ICarImpl 源碼世吨,我們得知 ICarImpl 是 ICar.Stub 的子類,查看 ICar.aidl呻征,得知耘婚,code = FIRST_CALL_TRANSACTION
時,實際調(diào)用的是setSystemServerConnections
方法,如圖:
sendSetSystemServerConnectionsCall在aidl中的值為0 - 也可以在系統(tǒng)編譯產(chǎn)物/out/target/common/obj/JAVA_LIBRARIES/android.car_intermediates/classes.jar中找到陆赋,解壓classes.jar沐祷,在android/car/ICar$Stub.class中,反編譯可以看到攒岛,在
onTransact
方法中赖临,code值為1時,對應的方法是sendSetSystemServerConnectionsCall
,如圖:
TRANSACTION_setSystemServerConnections = 1
case 1 : this.setSystemServerConnections(_arg0, _result);
- 查看實現(xiàn)類 ICarImpl 中的
sendSetSystemServerConnectionsCall
方法灾锯,將成員變量mICarServiceHelper
指向carServiceHelper
兢榨,并且將引用同步更新到各個功能模塊中,至此 CarService 可以通過mICarServiceHelper
進行跨進程通信,如圖:
mICarServiceHelper = carServiceHelper
下一章繼續(xù)分析CarOccupantZoneService和CarUserService的init中,做了什么