OpenHarmony系統是怎么知道應用是Ark應用的
背景
自從OpenHarmony系統3.0-LTS版本發布之后,OpenHarmony系統對JS應用增加了Ark方舟運行時,但之前的QuickJS運行時卻有沒有移除,就產生了兩個好奇的問題。
OpenHarmony系統中存在兩個JS運行時,那開發的JS應用到底是運行在哪個運行時中的?
OpenHarmony系統又是怎么識別Hap包是Ark JS應用的?
探究
第一步,確定系統是否真的存在Ark方舟運行時。
OpenHarmony系統源碼中,雖然提供了Ark方舟運行時代碼,但開發板編譯的系統不一定會編譯Ark方舟運行時。本人手中的開發板是Hi3516,所以去productdefine目錄下面查看了一下Hi3516DV300.json文件,確認是否Ark子系統是否參與了編譯。
從上圖可以看出,Ark子系統參與了系統編譯,那就去開發板系統下確認一下。通過hdc工具查看,hdc shell進入系統中,在system/lib 目錄下搜索ark字樣,結果顯示確實有Ark JS運行時libark_jsruntime.so。
從上圖結果中,還可以看出ace JS UI框架部分的so庫也有ark版本的。
第二步,確定Ace JS UI框架是否存在Ark和QuickJS同時支持。
繼續在hdc shell下搜索ace相關的so庫信息。
從上圖的信息中,Ace是同時支持Ark和QuickJS的。既然如此,那就去查看OpenHarmony的源碼吧,系統究竟是怎么進行識別Hap應用的類型的。
第三步,確認系統SO庫的選擇方式。
多年的程序開發經驗,讓我立馬就猜測,系統可能會有so庫的選擇過程,比如 libace_engine_ark.z.so 和 libace_engine_qjs.z.so 兩個的選擇。于是我就在OpenHarmony源碼下的foundation目錄下進行了 find 查找。
find 的結果真的印證我的猜測,真有相關代碼信息。那就去ace_container.cpp這個文件代碼的第54行去看看吧。
一看代碼,把我高興壞了,這不就是我猜測的結果么。通過函數的入參 isArkApp 進行選擇的。那就繼續找isArkApp 這個參數怎么來的吧。
第四步,確定 isArkApp 參數來源。
繼續發揮 find 命令的強大,搜索函數在哪里調用的。
結果是在同一個文件類調用的,查看源碼,發現還是AceContainer類里面一個 isArkApp_ 自由布爾變量。
再次在源碼里面找,發現是在AceContainer類構造函數中初始化的。
那就在使用 find 命令繼續搜索哪里有調用AceContainer類這個構造函數吧。結果有點失望,沒有搜到有調用的地方。沒有那就認真看看代碼吧,發現是AceContainer類內部一個 CreateContainer 的靜態函數構造的AceContainer實例,isArkApp 這個參數也是從 CreateContainer 函數傳進來的。
有了突破口,那就又繼續 find 吧(真的很強大啊)。
結果顯示在ace_ability.cpp文件的第256行代碼有調用。
查看源碼,找到了 isArkApp 參數的來源,是 GetIsArkFromConfig 這個函數的返回值。
第五步,查看GetIsArkFromConfig函數的代碼。
GetIsArkFromConfig 這個函數在 utils.h 文件中,實現如下所示,展示了關鍵代碼:
inline bool GetIsArkFromConfig(const std::string& packagePathStr)
{
auto configPath = packagePathStr + std::string("config.json");
//·····此處省略100字·····
std::string jsonString(jsonStream.get(), jsonStream.get() + size);
auto rootJson = JsonUtil::ParseJsonString(jsonString);
auto module = rootJson->GetValue("module");
auto distro = module->GetValue("distro");
std::string virtualMachine = distro->GetString("virtualMachine");
return virtualMachine.find("ark") != std::string::npos;
}
從上述代碼中可以看出,是解析的hap中的config.json文件中的內容,通過module/distro結構中的 virtualMachine 字段的值中是否包含有 ark 字符串來判斷的。至此,我們就找了OpenHarmony是怎么識別ARK應用的依據了。
第六步,解析Hap包確認config.json文件內容。
自己使用DevEco Studio開發了一個Demo應用,并打包成Hap包,再直接使用解壓工具解壓Hap文件,查看其中的config.json文件內容,內容如下:
distro對象中確實存在一個 virtualMachine 字段,而且內容為 ark0.0.0.2。但是實際上,寫代碼的時候config.json文件中的distro并沒有添加 virtualMachine 字段。如下所示:
所以可以得出,virtualMachine 這個字段是 DevEco Studio 開發工具編譯打包期間,自動添加進去的。
總結
當前 DevEco Studio 開發工具開發的OpenHarmony應用程序,已經默認編譯打包成了 Ark 應用。不需要開發人員手動設置。
疑問:DevEco Studio 開發工具已經默認OpenHarmony應用程序為Ark應用,那系統中的QuickJS還有用處嗎?