前言
在上一篇中已經完成了服務端的集成,手機軟件此時已經可以自動啓動服務端,且運行無異常。
接下來我們就要實現我們的終極目標了:system_server(JAVA端)與服務端相互通信;
預處理
首先先解釋下一個“玄學”的情況:在前兩章的操作完成後,我們不需要添加任何JAVA類,即可直接使用;
究其原因,是因爲在我們之前使用hidl-gen的時候,生成的Android.bp中包含這個字段:
hidl_interface {
...
gen_java: true,
}
字段定義與實現可在這裏查到:/system/tools/hidl/build/hidl_interface.go,在此先不講解,後續有時間再補上:
JAVA代碼
添加Android.bp依賴:
static_libs: [
"vendor.zsui.hardware.example-V1.0-java",
]
核心代碼:
import vendor.zsui.hardware.example.V1_0.IExample;
...
try {
IExample example = IExample.getService();
Slog.d("ZSUI", "example HELLO WORLD result = " + example.helloWorld("ZSUI"));
} catch (Exception e) {
e.printStackTrace();
}
...
需要注意一點,在[email protected]中我們定義該服務的類別爲HAL(class hal),這會導致它的啓動可能比system_server中的核心服務(AMS/PowerMS等)晚,所以實際使用中需要做容錯判斷;
至此,一切似乎都處理好了,編譯也通過了,是不是可以看到Hello World了呢?
02-26 12:33:21.407 449 449 W hwservicemanager: getTransport: Cannot find entry [email protected]::IExample/default in either framework or device manifest.
02-26 12:33:21.407 1467 1574 W System.err: java.util.NoSuchElementException
02-26 12:33:21.408 1467 1574 W System.err: at android.os.HwBinder.getService(Native Method)
02-26 12:33:21.408 1467 1574 W System.err: at android.os.HwBinder.getService(HwBinder.java:91)
02-26 12:33:21.408 1467 1574 W System.err: at vendor.zsui.hardware.example.V1_0.IExample.getService(IExample.java:48)
02-26 12:33:21.408 1467 1574 W System.err: at vendor.zsui.hardware.example.V1_0.IExample.getService(IExample.java:52)
02-26 12:33:21.408 1467 1574 W System.err: at com.android.server.am.ActivityManagerService.bootAnimationComplete(ActivityManagerService.java:8246)
02-26 12:33:21.408 1467 1574 W System.err: at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3495)
02-26 12:33:21.408 1467 1574 W System.err: at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:272)
02-26 12:33:21.408 1467 1574 W System.err: at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:4975)
02-26 12:33:21.408 1467 1574 W System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
02-26 12:33:21.408 1467 1574 W System.err: at android.os.Looper.loop(Looper.java:193)
02-26 12:33:21.408 1467 1574 W System.err: at android.os.HandlerThread.run(HandlerThread.java:65)
02-26 12:33:21.408 1467 1574 W System.err: at com.android.server.ServiceThread.run(ServiceThread.java:44)
這個是由於Vintf機制要求,需要在manifest.xml中聲明這個HIDL,因此將如下內容添加到對應文件中即可:
在device/<$vendor>/<$product>/manifest.xml或等效的位置添加:
<manifest version="1.0" type="device">
...
<hal format="hidl">
<name>vendor.zsui.hardware.example</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>IExample</name>
<instance>default</instance>
</interface>
</hal>
...
</manifest>
刷機,開機,一切正常:
02-26 12:46:22.879 1476 1562 D ZSUI : example HELLO WORLD result = Hello World, ZSUI
至此,連續三章的虛擬HAL創建步驟已經完成。
這三篇主要是步驟解讀,相信按照這個一步一步來,實際使用是沒有問題的。
但是這三篇並沒有對原理方面做過多解釋,因此之後會更新一篇Q&A,主要講解部分看似“玄學”的操作;
文筆有限,若有謬誤,還請指出;
感謝!