OpenHarmony系统是怎么知道应用是Ark应用的 原创 精华

拓维信息Abin
发布于 2022-3-11 18:43
浏览
8收藏

背景

​ 自从OpenHarmony系统3.0-LTS版本发布之后,OpenHarmony系统对JS应用增加了Ark方舟运行时,但之前的QuickJS运行时却有没有移除,就产生了两个好奇的问题。

  1. OpenHarmony系统中存在两个JS运行时,那开发的JS应用到底是运行在哪个运行时中的?
  2. OpenHarmony系统又是怎么识别Hap包是Ark JS应用的?

探究

第一步,确定系统是否真的存在Ark方舟运行时。

OpenHarmony系统源码中,虽然提供了Ark方舟运行时代码,但开发板编译的系统不一定会编译Ark方舟运行时。本人手中的开发板是Hi3516,所以去productdefine目录下面查看了一下Hi3516DV300.json文件,确认是否Ark子系统是否参与了编译。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

从上图可以看出,Ark子系统参与了系统编译,那就去开发板系统下确认一下。通过hdc工具查看,hdc shell进入系统中,在system/lib 目录下搜索ark字样,结果显示确实有Ark JS运行时libark_jsruntime.so

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

从上图结果中,还可以看出ace JS UI框架部分的so库也有ark版本的。

第二步,确定Ace JS UI框架是否存在Ark和QuickJS同时支持。

继续在hdc shell下搜索ace相关的so库信息。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

从上图的信息中,Ace是同时支持Ark和QuickJS的。既然如此,那就去查看OpenHarmony的源码吧,系统究竟是怎么进行识别Hap应用的类型的。

第三步,确认系统SO库的选择方式。

多年的程序开发经验,让我立马就猜测,系统可能会有so库的选择过程,比如 libace_engine_ark.z.solibace_engine_qjs.z.so 两个的选择。于是我就在OpenHarmony源码下的foundation目录下进行了 find 查找。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

find 的结果真的印证我的猜测,真有相关代码信息。那就去ace_container.cpp这个文件代码的第54行去看看吧。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

一看代码,把我高兴坏了,这不就是我猜测的结果么。通过函数的入参 isArkApp 进行选择的。那就继续找isArkApp 这个参数怎么来的吧。

第四步,确定 isArkApp 参数来源。

继续发挥 find 命令的强大,搜索函数在哪里调用的。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

结果是在同一个文件类调用的,查看源码,发现还是AceContainer类里面一个 isArkApp_ 自由布尔变量。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

再次在源码里面找,发现是在AceContainer类构造函数中初始化的。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

那就在使用 find 命令继续搜索哪里有调用AceContainer类这个构造函数吧。结果有点失望,没有搜到有调用的地方。没有那就认真看看代码吧,发现是AceContainer类内部一个 CreateContainer 的静态函数构造的AceContainer实例,isArkApp 这个参数也是从 CreateContainer 函数传进来的。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

有了突破口,那就又继续 find 吧(真的很强大啊)。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

结果显示在ace_ability.cpp文件的第256行代码有调用。

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

查看源码,找到了 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文件内容,内容如下:

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

distro对象中确实存在一个 virtualMachine 字段,而且内容为 ark0.0.0.2。但是实际上,写代码的时候config.json文件中的distro并没有添加 virtualMachine 字段。如下所示:

OpenHarmony系统是怎么知道应用是Ark应用的-鸿蒙开发者社区

所以可以得出,virtualMachine 这个字段是 DevEco Studio 开发工具编译打包期间,自动添加进去的。

总结

当前 DevEco Studio 开发工具开发的OpenHarmony应用程序,已经默认编译打包成了 Ark 应用。不需要开发人员手动设置。

疑问:DevEco Studio 开发工具已经默认OpenHarmony应用程序为Ark应用,那系统中的QuickJS还有用处吗?

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
11
收藏 8
回复
举报
3条回复
按时间正序
/
按时间倒序
民之码农
民之码农

666

1
回复
2022-3-14 07:59:33
如此之白
如此之白

666

1
回复
2022-3-14 14:22:15
zhushangyuan_
zhushangyuan_

666

1
回复
2022-3-15 08:37:03
回复
    相关推荐