优酷鸿蒙开发实践|优酷 Android 与HarmonyOS Hap 混合打包

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c7/c7c73a83994db10394f5998ded9b8b81.gif","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在","attrs":{}},{"type":"link","attrs":{"href":"https://juejin.cn/post/7018821032278491150/","title":"","type":null},"content":[{"type":"text","text":"《优酷鸿蒙开发实践|鸿蒙卡片开发》","attrs":{}}]},{"type":"text","text":"一文中已经提到,要实现“在优酷主客ICON向上滑动,呼出优酷鸿蒙卡片”,需要卡片的实现代码与优酷主客做混合打包。下面的小节简单介绍了如何实现Android/鸿蒙混合打包的流程。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当前,将大型Android应用(下图图1)全部使用鸿蒙API改写是不现实的,所以华为设计了上述的演进路线。希望将App中的功能由Android模块逐步替换为鸿蒙FA/PA, 并混合打包在一起进行分发(下图图2),最终抵达100% Pure 鸿蒙的最终形态(下图图3)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目前,我们将优酷Android主客和鸿蒙HAP混合打包为一个产物,也就是图中 “安卓App平滑演进及互操作”的中间态。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/00/00a747427cd11d7a1f5285a50e00c4da.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"刚才已经提到,当前的优酷鸿蒙专版包含Android APK主体,以及桌面Widget HAP, 多屏互动HAP。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,鸿蒙版优酷不仅拥有Android版优酷的的所有功能, 还拥有Android版不具备的一些特殊功能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优酷鸿蒙版是在早期吃螃蟹,和华为一起合作开发鸿蒙版App先行者之一,解决了大量实际工程难题,并且与华为共同解决了大量开发环境和运行时的Bug,最终顺利地让优酷鸿蒙混合包上架华为应用商店。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"打包方案Battle","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"分包方案","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"将原Android Apk应用和Harmony Hap(Hap为Harmony应用编译产物,跟Apk角色一致)应用分别上架应用市场。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:Apk和Hap可以不同包名,单独控制版本上架","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:用户需要同时下载安装 2次才可以体验完整功能","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"混合包方案","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"将原Android Apk和Harmony Hap混合打包成App上架应用市场。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"优点:用户下载安装 1 次即可体验完整功能,不必担心2个应用版本差异","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺点:打包生产相对麻烦,对apk和hap有同包名限制","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对比下,分包方案需要安装2次才可以完成整体功能体验,这显然是硬伤,合包方案虽然在开发生产侧麻烦一些,但可以给用户带来较好的体验,所以选择了混合包方案。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"混合包","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"什么是混合包?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Android的产物是Apk,Harmony的产物是Hap,将Apk和Hap混合打成一个总产物包称作为混合包(APP)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/bc/bc9561eccc8cf6b4d7768eeab5deef73.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"混合包使用场景","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"场景1:当Harmony版应用并不是一个完整的功能,而只是作为原有Android应用的能力补充和增强时,需要将apk和hap打包成一个整应用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"场景2:Android应用短时间内无法全部迁移成Harmony版,分节奏迁移过程中可采用此方案进行混合打包作为一个供Harmony系统可运行的应用。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"混合包打包流程","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/66/6648991578dfc6d3e8a2a3dd5e29f4d6.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"名词解释:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"legacyApk","attrs":{}},{"type":"text","text":":在原有正常Android工程和混合打包插件编译出的apk产物,此apk不能独立安装和运行,仅用于生产鸿蒙最终app的中间产物。如上图:混合打包流程实际就是将legacyApk(经过加工的原Android Apk产物)和鸿蒙应用产物Hap打包成一个App包(zip)的过程。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"混合包要求及限制","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"名词解释:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"鸿蒙entry:","attrs":{}},{"type":"text","text":" 对应Android的application;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"鸿蒙feature:","attrs":{}},{"type":"text","text":" 对应Android的module或bundle。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"限制:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"鸿蒙工程entry中将作为apk的父容器,所以不能包含任何代码和资源,需将所有的代码和资源移到feature中;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"鸿蒙entry和feature们的config.json中必须保持一致,并且与Android的versionCode versionName保持一致;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Android应用(legacyApk)必须为64位包,不能包含32位的so。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"要求:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"鸿蒙应用必须与原Android应用同包名;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"混合打包要求hap(类Android的agp)版本 >= 2.4.2.2,apiVersion(类Android的targetSdkVersion)需要>=5;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"鸿蒙应用启动时实际还是单独应用,为了保持跟原Android技术品牌一致,需要保持entry中的config.json中的label和icon与原安卓应用中一致。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"生成步骤","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"第一步:原Android Apk侧修改","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了干预原Apk的启动流程,增加鸿蒙应用的启动入口,需要干预Android的application。鸿蒙侧提供了工程侧打包编译的plugin,但由于优酷是组件化开发模式,application作为一个单独的aar模块存在,所以混合编译plugin并不是适用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"方案:通过了解混合编译plugin的职责,直接在application模块手动修改父类为AceHarmonyApplication(ohos.ace.ability.AceHarmonyApplication,此类在鸿蒙提供abilityshell.jar中),并手动在manifest中添加用于鸿蒙兼容性属性如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n \n \n \n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"将application模块集成进Android工程,编译后得到产物legacyApk。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"第二步:鸿蒙工程侧修改","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1、配置工程参数","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"build.gradle","attrs":{}},{"type":"text","text":":entry和所有feature中的build.gradle的compileSdkVersion、compatibleSdkVersion改成5(混合包最小支持版本要求为5);","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"config.json","attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"entry和所有feature中的config.json的apiVersion中的compatible和target改成5;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"entry和所有feature中添加originalName属性并保持跟bundleName一致;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"entry和所有feature中添加version,并保持子属性code等于Apk中的versionCode,子属性等于Apk中的versionName;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"entry和所有feature中的vendor保持一致,config.json中的code和name有要求,name推荐为三段式\"a.b.c\" Code值为a","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"1000000+b","attrs":{}},{"type":"text","text":"1000+c。如Name为1.001.003,Code值为1001003。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"{\n “app”:{\n \n \"bundleName”:”包名”, //这是鸿蒙应用包名,混合包要求必须与Apk包名一致\n \"vendor”:”xxx”,//entry和feature中要一致\n \"version\":{\n \"code\":xxx,//对应Android VersionCode要求高于apk版本,并且根据name拼接而成\n \"name”:”xxx” //对应Android VersionName\n },\n \"apiVersion\":{\n \"compatible\":5,//5才支持混合包\n \"target\":5,\n \"releaseType\":\"Release\"\n }\n \n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"2、在entry模块添加legacyApkOptions配置","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"apply plugin: 'com.huawei.ohos.hap'\nohos { \n ...\n legacyApkOptions {\n legacyApk\"..\\..\\legacy_entry.apk\" //指向legecyApk文件,并且必须以entry.apk结尾\n legacyVersionCode \"499\" // 与 legacyApk 的 AndroidManifest.xml 中配置的android:versionCode 保持一致\n legacyVersionName \"9.15.2\" // 与 legacyApk 的 AndroidManifest.xml 中配置的android:versionName 保持一致 \n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"3、entry修改","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"将entry中的所有代码和资源移到feature中(鸿蒙工程允许有一个entry,可以有多个feature);添加一个空的Ability页面,并修改icon和label与原Android应用一致。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"第三步:签名","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"签名是混合打包中最麻烦的一步,这也是鸿蒙开发最特殊的一步,需要拿原签名文件(jks或者p12)用DevEco Studio生成csr,然后去华为应用市场申请签名的证书(cer)文件和Profile(p7b)文件,更多详情也参考华为帮助文档(https://developer.huawei.com/consumer/cn/doc/distribution/app/agc-help-harmonyos-debugapp-0000001058642113)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由于混合包要求APP的签名信息要与原Android的签名信息一致,所以正常情况下用原Android的签名文件(jks)就可以了,但鸿蒙为了安全性,提升了签名的安全性要求:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"必须使用EC算法","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"密钥密码要”大小写字母/数字/ 特殊字 符,至少两种的组合,长度大于等于 8","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果签名文件构建的时间比较早,这两个要求都不符合的话,华为侧提供了如下解决方案:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、可以使用原Android签名文件单独配置shell Apk签名","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"apply plugin: 'com.huawei.ohos.hap'\nohos {\n ... \n legacyApkOptions {\n ... \n signConfig {\n storeFile file(\"..\\legacyApkJks.jks\") // 单独配置的 shell apk 签名材料\n }\n ... \n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、使用keytool命令行生成p12文件和csr文件,但要求别名和秘钥跟原Android签名保持一致,并且使用EC算法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"//生成p12\nkeytool -genkey -alias [keyname] -keystore [p12.file] -storetype pkcs12 -keyalg EC -keypass [password] -storepass [password]\n\n//生成csr\nkeytool -certreq -alias [keyname] -keystore [p12.file] -storetype pkcs12 -file [csr.file]\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"申请下来cer和p7b文件(需要单独申请调试和发布证书)后,就可以在开发工具中配置签名文件了(更多配置详情也阅览华为配置签名帮助文档 https://developer.harmonyos.com/cn/docs/documentation/doc-guides/publish_app-0000001053223745#ZH-CN_TOPIC_0000001058015911__section9752152162813)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然后通过开发工具DevEco Studio中build -> Build Apps编译得到产物APP。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"工程结构概述:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/52/52af0c12694b8384994940231ba03399.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"混合包产物分析","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"经过上面的一系列流程,就可以生成一个供鸿蒙运行的混合包了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由于是发布证书签名,这个混合包实际上是不能直接手动安装到Harmony OS上,还需要经过华为平台侧(需要联系华为侧接口人)签名,提供转换之后的安装包供优酷方面测试使用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"测试完毕之后,可以直接拿这个混合包上架到华为的鸿蒙应用市场。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"鸿蒙版本发版经验总结","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"鸿蒙混合包只有64位包;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"鸿蒙混合包在鸿蒙市场发版节奏、版本号等最好是跟原安卓发版节奏、版本号等保持一致,不然需要特殊考虑鸿蒙版本的数据定投问题;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"apk和hap在app中实际是物理区分,打包app的时候并不会把apk重新编译,所以如果apk和hap存在同名的类(因为都是java类),根据双亲委派机制,在运行时将会出现问题;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果原安卓应用包含通讯录、拨打电话权限,在华为平台申请p7b文件时一定需要勾选申请使用受限权限,如下图:","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/2c/2cad4b70d9e2d1cead20c7af55b36157.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最后,下周《优酷鸿蒙开发实践》系列第三篇技术文章,我们将以优酷播放中心的技术储备为切入点,结合鸿蒙系统的镜像和流转特性,详细介绍普通流转、自由视角和zoom 等核心能力在鸿蒙上的实践之路。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"感谢关注【阿里巴巴移动技术】,我们下篇技术实践再见。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}},{"type":"strong","attrs":{}}],"text":"关注我们,每周 3 篇移动技术实践&干货给你思考!","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章