當前位置:編程學習大全網 - 源碼下載 - 02 項目架構-IPC通信框架

02 項目架構-IPC通信框架

Android App開發中的IPC(進程間通信)無處不在。比如我們使用的 AlarmManager 、 InputMethodService 都是系統為我們提供的服務,處於單獨的進程中。如果需要在自己的App進程中使用這些服務就需要進行IPC通信。

除此之外,我們自己的程序中也會存在進程通信的可能(特別是在壹些大型APP中)

QQ:未登陸

微信:使用壹段時間後:

場景:在Service中開啟定位服務,Service處於單獨的進程,需要在App主進程或者其他APP中獲得定位結果。

服務中提供暴露給其他進程使用的方法並提供壹個 ServiceId 註解標記,而服務實現中必須給到相同的 ServiceId 與方法實現,不強制要求 LocationManager 壹定需要繼承 ILocationManager j接口,但是為了保證方法簽名統壹建議繼承。(不然壹個是getLocation,另壹個是getLocation2就不好玩了)

在Service進行定位,定位結果在 LocationManager 中記錄。在這個Service中使用框架註冊 LocationManager 。

不需要返回 Binder 對象,這意味著使用者不需要編寫繁瑣沒任何提示的AIDL文件。

框架內部會提供 com.enjoy.ipc.IPCService$IPCServiceX 多個預留Service,用於與其他進程通信,如果壹個App存在多個進程都需要提供各自進程的服務,可以使用不同的Service。所以本質上依然是借助的Service+Binder通信,但框架將細節封裝隱藏,使用更加簡單。

獲得結果對象後就能像調用本地方法壹樣調用遠程方法(RPC調用)。

在使用中簡化了:

1、不需要自己定義AIDL接口,使用的JavaBean也不要求實現 Parcelable 接口;

2、在客戶端不需要直接使用 bindService 獲得 Binder 對象;

服務端需要定義暴露服務的接口(ILocationManager),客戶端如果是其他APP,則需要將接口類放到自己的源碼中(不需要接口實現)。接口中定義的方法就是服務端提供給其他進程使用的方法。

整個框架包含了服務端與客戶端兩端接口。

在服務進程中會緩存 ServiceId 與對應的服務實現Class對象: 服務表 ,同時服務實現中的所有方法列表也需要進行記錄: 方法表 。由於壹個服務中可能存在多個方法,所以其數據結構為 Map<Class,Map<String,Method>> ,外層 Map 的key為服務Class,內層 Map 的key則為方法標記。

當客戶端需要調用服務時,將 ServiceId 、MethodName以及執行方法需要的參數傳遞給服務端,服務端查表利用反射 Method#invoke 即可執行服務中的方法。

其中客戶端的請求被封裝為 Request 對象,服務端響應則封裝為 Response 對象

服務端只需要暴露服務接口給其他進程使用,所以服務端只需要調用框架的註冊接口 regiest 對服務實現進行註冊。( 註冊的是服務實現,而不是服務接口 )

註冊時,通過反射獲得Class上的 ServiceId 即可記錄 服務表 。同時利用反射獲得Class中所有的public Method即可記錄 方法表

由於框架本質還是利用Binder來完成通信,為了與其他進程通信,框架內部提供了多個預留的Service。

通信Service會返回壹個AIDL生成的Binder類對象

客戶端使用 send 方法向服務端發起請求。

服務端接收到請求後的實現:

客戶端需要先與服務端建立連接,因此框架中提供了 connect 方法,內部封裝 bindService 實現與服務端通信Service( IPCService )的綁定。

唯壹需要註意的是:

當完成綁定後,客戶端就可以獲得服務端通信Service提供的 IIPCService 對象,客戶端調用 IIPCService#send 發起請求。

當我們需要獲得 Location 。則應該調用 LocationManager.getDefault().getLocation() 。這句調用會需要執行 LocationManager 的兩個方法: getDefault 與 getLocation 。

然而這個對象存在服務端,客戶端如何獲得?

我們可以利用動態代理,在客戶端創建壹個 "假的" 服務接口對象(代理)。

當我們執行這個代理對象的方法( getLocation )時,會回調 IPCInvocationHandler#invoke 方法,在這個方法中框架會向服務端發起請求: IIPCService#send

而 getLocation 會返回壹個 Location 記錄定位信息的對象,這個對象會被服務端json序列化發送過來,因此,客戶端只需要在此處獲得 Method 的返回類型並反序列化即可。

RPC指的是:從客戶端上通過參數傳遞的方式調用服務器上的壹個函數並得到返回的結果,隱藏底層的通訊細節。在使用形式上像調用本地函數壹樣去調用遠程的函數。

比如我們使用Okhttp進行網絡請求:

這種方式很顯然不是RPC。

而使用Retrofit:

RPC:我們調用遠程的XXX方法,就像在調用本地方法壹樣。

  • 上一篇:手機卡莫名其妙的顯示無服務怎麽回事
  • 下一篇:Pythoncrypt源代碼
  • copyright 2024編程學習大全網