前言
App与Hap,Entry与feature,bundleName与packge这几个关键字是HarmonyOS入门基础中必讲的,也是我们最容易忽略的知识点,而又真需要用到它们时,往往又会因为没完全弄明白它们的意思导致混淆不清,导致因为它们产生的问题而找不出原因。
因为前期在刚入门的时候往往没有它们的典型案例,特别是比较深的对比案例做演示,往往会导致对它们的理解不够清晰。下面我就结合它们案例和具体因为它们导致的bug来做对比后详细讲解,相信大家看完我这篇文章之后会完全理解它们的重要作用了,也不会再轻视它们了。
App与Hap、Entry与feature
下面先直接引用官网的一段描述。
官网这小小的一段话,其实信息量还是很大的,特别是刚入门的时候看这段话,往往会一知半解,所以好多知识是要反复咀嚼才行,即刚开始入门的时候看一遍,学到中途的时候涉及到相关知识再来看一遍,后面学到一定程度了再回头复盘看一遍就会又有另一番滋味。
App包是我们最终使用DevEco Studio打包发布到华为应用市场的软件包,如何打包成App包呢,如下图:
打包之后的App包所在的位置如下图:
在哪里发布这个App包呢,如下图:
发布到应用市场等待官方审核完成之后,你就可以在手机上通过应用市场安装该应用了。
最后关于App包来个点睛的话:App包不能直接安装到手机上运行,即不能通过hdc工具安装,也不能拷贝到手机上之后点击安装,它仅仅用来向应用商店发布。
那么我发布之前该如何进行调试呢?发布之前只能借助hap包来调试了。
我们在DevEco Studio中还可以build出hap,如果鼠标选中单个module开始build,则只会构建该module的hap包,如果选中整个工程project开始build,则工程下的所有module都会构建hap包,hap包构建完成之后的位置如下图:
我的工程里面有两个module,分别为entry和myapplication,而myapplication为feature类型,并且该feature是携带FA的。
上面的entry和myapplication都携带了FA,即都有UI页面,它们都可以在调试阶段直接通过hdc工具安装到手机上独立运行调试,并且都有各自的UI页面,但是我们安装到手机上之后会发现一个重要区别,entry会在桌面上创建一个入口图标,而feature是没有入口图标的。也就是说Feature你没法直接通过桌面入口去打开它的,它最终发布的时候会附加在整个App包中进行发布,发布之后可以通过在ability相关的api接口来调起来feature中的相关FA。
这里有个比较坑的点就是,由于feature和entry共用的同一个bundleName,而手机上同一个bundleName的应用只能安装一个,在调试阶段每个hap都被当做了一个独立应用,就导致了这两个hap不能在手机上同时安装,安装一个就会自动先卸载掉另一个,但是在以app包发布之后是可以的,因为app包是一个独立应用(里面包含多个hap,正式发布之后独立应用是以app为单位的而不是hap了)。这里就会带来一个实际项目生产中的大问题,比如我做了一个大项目应用,里面有一个entry同时还会有很多feature,我调试阶段同一个手机无法同时安装这些entry和feature进行测试,而我打成app包又不能安装到手机上进行测试,等发布到应用商店之后再来测试那就更扯淡了。相信很多大厂在做HarmonyOS应用开发的时候都遇到这个问题了吧。
这里我只能给个体验感不太好的解决方案,那就是在调试阶段给每个hap都取用不同的bundleName,以及代码中需要使用的bundleName都要同步修改,待测试完成之后,在发布之前全部统一修改回同一个bundleName。
bundleName与package
在上面已经提到了bundleName的一个重要作用,下面就来具体分析下bundleName与package这两个概念的对比以及坑点,防止大家混淆和入坑。
首先还是来看官网描述bundleName和package的解释,如下图:
官网说了bundleName是应用的包名,如果是从java或者Android开发过来的朋友估计就晕了,会误以为这不就是package吗?
其实去掉它表示应用的包名这句话就更好理解了,直接说它是应用的唯一标识符,即你的手机上不能同时安装有两个bundleName一样的应用。在Android开发从eclipse过度到Android studio开发之后,在gradle配置中加入了一个applicationId,这个bundleName其实是和applicationId对标的。关于这个唯一标识的作用,在上面讲解App与Hap的时候已经详细讲解了,这里就不再重复赘述了。
package是真正的包名,它是每个hap的包结构名称,同一个App下的bundleName相同,但是package名称不同,这个就是我们通常java中提到的包名了,比如有一个类名为MainAbility,它所属的包名为com.xdw.jstest,我们在好多api接口使用的时候经常会调用完整类名,即com.xdw.jstest.MainAbility。下面就结合一个核心Js Api来讲解bundleName和package结合使用的应用场景,容易混淆出错的地方。这里顺带提一下,从Api8之后HarmonyOS也完全抛弃java了,这里用的api也是8版本。
截取官网上的一个api使用描述,如下图:
以后遇到这种api就要长个心眼,下面abilityName中前面的那一长串是package,而不是bundleName,官网截图中它们是同一串字符串,但是千万不要误以为它们必须一样,在调用这类api的时候一定要仔细去module下的config.json文件中分别复制自己的bundleName和package,特别是最新的992版本的DevEco Studio开发工具在创建工程的时候只提供输入bundleName的地方而不提供输入package的地方,并且默认生成的package和bundleName是不一样的,如果你这里想当然的它们就是一样的,那么调用上图中的api的时候就会导致api无法生效。
小结
相信读完全篇文档之后,大家不会再对这些重要概念再混淆不清了吧。