一、什么是Hermes?
Hermes是餓了么提供的一個開源框架,實現(xiàn)跨進程通信。
它不需要通過aidl實現(xiàn)跨進程。
二、如何使用Hermes?
有個小需求:A進程有個單例UserManager,里面能對內(nèi)部的成員變量name賦值,現(xiàn)在A進程賦值name這個變量后,在B進程需要拿到name賦值后的結(jié)果。怎么實現(xiàn)呢?
上一篇我們知道兩個進程之間的內(nèi)存區(qū)域是不一樣的,雖然B進程能拿到A進程的單例對象,但是兩個單例對象名字相同,但是本質(zhì)不同,所以無法進行數(shù)據(jù)上的交互。這時就需要有個代理的接口IUserManager,通過注解@ClassId的方式,將IUserManager與UserManager一一對應(yīng)起來:
image.png
A進程的MainActivity里面先初始化Hermes,然后調(diào)用單例類UserManager的賦值方法:
image.png
B進程的SecondActivity先連接Hermes服務(wù),再獲取IUserManager接口,接口的getName方法,就是A進程UserManager的getName方法,通過注解產(chǎn)生一一對應(yīng)的關(guān)系
image.png
另外不要忘記注冊Hermes的服務(wù):
image.png
三、Hermes架構(gòu)分析及手寫實現(xiàn)
我先給大家總結(jié)一下通信的難點所在:
1.如何實現(xiàn)子線程與主線程之間的交互通信?
2.如何實現(xiàn)跨進程之間的通信?
3.使用Hermes架構(gòu)為何不用我們再次新增加AIDL文件?
第一點我們在上一篇文章已經(jīng)說明了怎么解決子線程與主線程之間的交互通信,現(xiàn)在回答第二點,Android跨進程通信必須要通過AIDL定義的接口再結(jié)合Binder機制實現(xiàn),所以EventBus想要實現(xiàn)跨進程,就必須增加AIDL文件,那么Hermes就是基于EventBus的底層封裝。再回到第三點,Hermes其實內(nèi)部定義了Request.aidl和Responce.aidl兩個最基本的請求和返回的aidl,另外再定義了一個EventBusService.aidl,它結(jié)合了前兩個aidl,將所有請求用Request這個基類表示,再將所有返回用Responce這個基類表示。
好了,接下來又會面臨另外個棘手的問題:我們自定義的普通數(shù)據(jù)類怎么讓它跨進程呢?此時Hermes內(nèi)部是將需要跨進程的類,拆分成Json格式的字符串,將跨進程的類名、執(zhí)行的方法、方法的返回接口、方法的參數(shù)這些全都用String來表示,然后拼接成JsonString的格式,來實現(xiàn)跨進程傳輸,傳輸成功后,再另外的進程再次解析參數(shù),找到對應(yīng)的類,執(zhí)行對應(yīng)的方法。這就是大體的流程。
思維導(dǎo)圖:
image.png
最后,B進程通過Binder拿到了A進程執(zhí)行的返回結(jié)果Responce,那么還要不要再通過反射獲得UserManager這個對象呢?肯定不需要,因為B進程壓根就不知道UserManager這個類,它只是知道有IUserManager這個接口,那么B進程怎么調(diào)用A進程的UserManager里面的方法呢?這里用到了動態(tài)代理,讓B進程誤以為它拿到了A進程的真實對象,其實這一切都是代理類提供的假象:
image.png
所以說代理設(shè)計模式在架構(gòu)中用的很廣泛,同學(xué)們需要掌握。
Demo地址:
https://github.com/cWX411904/MyEventBus





