OpenHarmony系統(tǒng)是怎么知道應(yīng)用是Ark應(yīng)用的
??51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)??
背景
自從OpenHarmony系統(tǒng)3.0-LTS版本發(fā)布之后,OpenHarmony系統(tǒng)對JS應(yīng)用增加了Ark方舟運(yùn)行時,但之前的QuickJS運(yùn)行時卻有沒有移除,就產(chǎn)生了兩個好奇的問題。
OpenHarmony系統(tǒng)中存在兩個JS運(yùn)行時,那開發(fā)的JS應(yīng)用到底是運(yùn)行在哪個運(yùn)行時中的?
OpenHarmony系統(tǒng)又是怎么識別Hap包是Ark JS應(yīng)用的?
探究
第一步,確定系統(tǒng)是否真的存在Ark方舟運(yùn)行時。
OpenHarmony系統(tǒng)源碼中,雖然提供了Ark方舟運(yùn)行時代碼,但開發(fā)板編譯的系統(tǒng)不一定會編譯Ark方舟運(yùn)行時。本人手中的開發(fā)板是Hi3516,所以去productdefine目錄下面查看了一下Hi3516DV300.json文件,確認(rèn)是否Ark子系統(tǒng)是否參與了編譯。
從上圖可以看出,Ark子系統(tǒng)參與了系統(tǒng)編譯,那就去開發(fā)板系統(tǒng)下確認(rèn)一下。通過hdc工具查看,hdc shell進(jìn)入系統(tǒng)中,在system/lib 目錄下搜索ark字樣,結(jié)果顯示確實(shí)有Ark JS運(yùn)行時libark_jsruntime.so。
從上圖結(jié)果中,還可以看出ace JS UI框架部分的so庫也有ark版本的。
第二步,確定Ace JS UI框架是否存在Ark和QuickJS同時支持。
繼續(xù)在hdc shell下搜索ace相關(guān)的so庫信息。
從上圖的信息中,Ace是同時支持Ark和QuickJS的。既然如此,那就去查看OpenHarmony的源碼吧,系統(tǒng)究竟是怎么進(jìn)行識別Hap應(yīng)用的類型的。
第三步,確認(rèn)系統(tǒng)SO庫的選擇方式。
多年的程序開發(fā)經(jīng)驗(yàn),讓我立馬就猜測,系統(tǒng)可能會有so庫的選擇過程,比如 libace_engine_ark.z.so 和 libace_engine_qjs.z.so 兩個的選擇。于是我就在OpenHarmony源碼下的foundation目錄下進(jìn)行了 find 查找。
find 的結(jié)果真的印證我的猜測,真有相關(guān)代碼信息。那就去ace_container.cpp這個文件代碼的第54行去看看吧。
一看代碼,把我高興壞了,這不就是我猜測的結(jié)果么。通過函數(shù)的入?yún)?isArkApp 進(jìn)行選擇的。那就繼續(xù)找isArkApp 這個參數(shù)怎么來的吧。
第四步,確定 isArkApp 參數(shù)來源。
繼續(xù)發(fā)揮 find 命令的強(qiáng)大,搜索函數(shù)在哪里調(diào)用的。
結(jié)果是在同一個文件類調(diào)用的,查看源碼,發(fā)現(xiàn)還是AceContainer類里面一個 isArkApp_ 自由布爾變量。
再次在源碼里面找,發(fā)現(xiàn)是在AceContainer類構(gòu)造函數(shù)中初始化的。
那就在使用 find 命令繼續(xù)搜索哪里有調(diào)用AceContainer類這個構(gòu)造函數(shù)吧。結(jié)果有點(diǎn)失望,沒有搜到有調(diào)用的地方。沒有那就認(rèn)真看看代碼吧,發(fā)現(xiàn)是AceContainer類內(nèi)部一個 CreateContainer 的靜態(tài)函數(shù)構(gòu)造的AceContainer實(shí)例,isArkApp 這個參數(shù)也是從 CreateContainer 函數(shù)傳進(jìn)來的。
有了突破口,那就又繼續(xù) find 吧(真的很強(qiáng)大啊)。
結(jié)果顯示在ace_ability.cpp文件的第256行代碼有調(diào)用。
查看源碼,找到了 isArkApp 參數(shù)的來源,是 GetIsArkFromConfig 這個函數(shù)的返回值。
第五步,查看GetIsArkFromConfig函數(shù)的代碼。
GetIsArkFromConfig 這個函數(shù)在 utils.h 文件中,實(shí)現(xiàn)如下所示,展示了關(guān)鍵代碼:
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文件中的內(nèi)容,通過module/distro結(jié)構(gòu)中的 virtualMachine 字段的值中是否包含有 ark 字符串來判斷的。至此,我們就找了OpenHarmony是怎么識別ARK應(yīng)用的依據(jù)了。
第六步,解析Hap包確認(rèn)config.json文件內(nèi)容。
自己使用DevEco Studio開發(fā)了一個Demo應(yīng)用,并打包成Hap包,再直接使用解壓工具解壓Hap文件,查看其中的config.json文件內(nèi)容,內(nèi)容如下:
distro對象中確實(shí)存在一個 virtualMachine 字段,而且內(nèi)容為 ark0.0.0.2。但是實(shí)際上,寫代碼的時候config.json文件中的distro并沒有添加 virtualMachine 字段。如下所示:
所以可以得出,virtualMachine 這個字段是 DevEco Studio 開發(fā)工具編譯打包期間,自動添加進(jìn)去的。
總結(jié)
當(dāng)前 DevEco Studio 開發(fā)工具開發(fā)的OpenHarmony應(yīng)用程序,已經(jīng)默認(rèn)編譯打包成了 Ark 應(yīng)用。不需要開發(fā)人員手動設(shè)置。
疑問:DevEco Studio 開發(fā)工具已經(jīng)默認(rèn)OpenHarmony應(yīng)用程序?yàn)锳rk應(yīng)用,那系統(tǒng)中的QuickJS還有用處嗎?
??51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)??