優酷鴻蒙開發實踐|優酷 Android 與HarmonyOS Hap 混合打包

阿里巴巴移動技術發表於2021-10-27

《優酷鴻蒙開發實踐|鴻蒙卡片開發》一文中已經提到,要實現“在優酷主客ICON向上滑動,撥出優酷鴻蒙卡片”,需要卡片的實現程式碼與優酷主客做混合打包。下面的小節簡單介紹瞭如何實現Android/鴻蒙混合打包的流程。

當前,將大型Android應用(下圖圖1)全部使用鴻蒙API改寫是不現實的,所以華為設計了上述的演進路線。希望將App中的功能由Android模組逐步替換為鴻蒙FA/PA, 並混合打包在一起進行分發(下圖圖2),最終抵達100% Pure 鴻蒙的最終形態(下圖圖3)。

目前,我們將優酷Android主客和鴻蒙HAP混合打包為一個產物,也就是圖中 “安卓App平滑演進及互操作”的中間態。

剛才已經提到,當前的優酷鴻蒙專版包含Android APK主體,以及桌面Widget HAP, 多屏互動HAP。

因此,鴻蒙版優酷不僅擁有Android版優酷的的所有功能, 還擁有Android版不具備的一些特殊功能。

優酷鴻蒙版是在早期吃螃蟹,和華為一起合作開發鴻蒙版App先行者之一,解決了大量實際工程難題,並且與華為共同解決了大量開發環境和執行時的Bug,最終順利地讓優酷鴻蒙混合包上架華為應用商店。

打包方案Battle

分包方案

將原Android Apk應用和Harmony Hap(Hap為Harmony應用編譯產物,跟Apk角色一致)應用分別上架應用市場。

  • 優點:Apk和Hap可以不同包名,單獨控制版本上架
  • 缺點:使用者需要同時下載安裝 2次才可以體驗完整功能

混合包方案

將原Android Apk和Harmony Hap混合打包成App上架應用市場。

  • 優點:使用者下載安裝 1 次即可體驗完整功能,不必擔心2個應用版本差異
  • 缺點:打包生產相對麻煩,對apk和hap有同包名限制

對比下,分包方案需要安裝2次才可以完成整體功能體驗,這顯然是硬傷,合包方案雖然在開發生產側麻煩一些,但可以給使用者帶來較好的體驗,所以選擇了混合包方案。

混合包

什麼是混合包?

Android的產物是Apk,Harmony的產物是Hap,將Apk和Hap混合打成一個總產物包稱作為混合包(APP)。

混合包使用場景

場景1:當Harmony版應用並不是一個完整的功能,而只是作為原有Android應用的能力補充和增強時,需要將apk和hap打包成一個整應用。

場景2:Android應用短時間內無法全部遷移成Harmony版,分節奏遷移過程中可採用此方案進行混合打包作為一個供Harmony系統可執行的應用。

混合包打包流程

名詞解釋:

  • legacyApk:在原有正常Android工程和混合打包外掛編譯出的apk產物,此apk不能獨立安裝和執行,僅用於生產鴻蒙最終app的中間產物。如上圖:混合打包流程實際就是將legacyApk(經過加工的原Android Apk產物)和鴻蒙應用產物Hap打包成一個App包(zip)的過程。

混合包要求及限制

名詞解釋:

  • 鴻蒙entry: 對應Android的application;
  • 鴻蒙feature: 對應Android的module或bundle。

限制:

  • 鴻蒙工程entry中將作為apk的父容器,所以不能包含任何程式碼和資源,需將所有的程式碼和資源移到feature中;
  • 鴻蒙entry和feature們的config.json中必須保持一致,並且與Android的versionCode versionName保持一致;
  • Android應用(legacyApk)必須為64位包,不能包含32位的so。

要求:

  • 鴻蒙應用必須與原Android應用同包名;
  • 混合打包要求hap(類Android的agp)版本 >= 2.4.2.2,apiVersion(類Android的targetSdkVersion)需要>=5;
  • 鴻蒙應用啟動時實際還是單獨應用,為了保持跟原Android技術品牌一致,需要保持entry中的config.json中的label和icon與原安卓應用中一致。

生成步驟

第一步:原Android Apk側修改

為了干預原Apk的啟動流程,增加鴻蒙應用的啟動入口,需要干預Android的application。鴻蒙側提供了工程側打包編譯的plugin,但由於優酷是元件化開發模式,application作為一個單獨的aar模組存在,所以混合編譯plugin並不是適用。

方案:通過了解混合編譯plugin的職責,直接在application模組手動修改父類為AceHarmonyApplication(ohos.ace.ability.AceHarmonyApplication,此類在鴻蒙提供abilityshell.jar中),並手動在manifest中新增用於鴻蒙相容性屬性如下:

<!--鴻蒙相容性屬性-->
 <uses-feature android:name="zidane.software.ability" 
     android:required="false" /> 
         <meta-data android:name="permZA" android:value="true" /> 
             <meta-data android:name="multiFrameworkBundle" android:value="true" />

將application模組整合進Android工程,編譯後得到產物legacyApk。

第二步:鴻蒙工程側修改

1、配置工程引數

build.gradle:entry和所有feature中的build.gradle的compileSdkVersion、compatibleSdkVersion改成5(混合包最小支援版本要求為5);

config.json

  • entry和所有feature中的config.json的apiVersion中的compatible和target改成5;
  • entry和所有feature中新增originalName屬性並保持跟bundleName一致;
  • entry和所有feature中新增version,並保持子屬性code等於Apk中的versionCode,子屬性等於Apk中的versionName;
  • entry和所有feature中的vendor保持一致,config.json中的code和name有要求,name推薦為三段式"a.b.c" Code值為a1000000+b1000+c。如Name為1.001.003,Code值為1001003。
{
   “app”:{
     
        "bundleName”:”包名”, //這是鴻蒙應用包名,混合包要求必須與Apk包名一致
        "vendor”:”xxx”,//entry和feature中要一致
        "version":{
            "code":xxx,//對應Android VersionCode要求高於apk版本,並且根據name拼接而成
            "name”:”xxx” //對應Android VersionName
        },
        "apiVersion":{
            "compatible":5,//5才支援混合包
            "target":5,
            "releaseType":"Release"
        }
     
   }
}

2、在entry模組新增legacyApkOptions配置

apply plugin: 'com.huawei.ohos.hap'
ohos { 
     ...
    legacyApkOptions {
        legacyApk"..\..\legacy_entry.apk" //指向legecyApk檔案,並且必須以entry.apk結尾
        legacyVersionCode "499" // 與 legacyApk 的 AndroidManifest.xml 中配置的android:versionCode 保持一致
        legacyVersionName "9.15.2" // 與 legacyApk 的 AndroidManifest.xml 中配置的android:versionName 保持一致 
    }
}

3、entry修改

將entry中的所有程式碼和資源移到feature中(鴻蒙工程允許有一個entry,可以有多個feature);新增一個空的Ability頁面,並修改icon和label與原Android應用一致。

第三步:簽名

簽名是混合打包中最麻煩的一步,這也是鴻蒙開發最特殊的一步,需要拿原簽名檔案(jks或者p12)用DevEco Studio生成csr,然後去華為應用市場申請簽名的證照(cer)檔案和Profile(p7b)檔案,更多詳情也參考華為幫助文件(https://developer.huawei.com/...

由於混合包要求APP的簽名資訊要與原Android的簽名資訊一致,所以正常情況下用原Android的簽名檔案(jks)就可以了,但鴻蒙為了安全性,提升了簽名的安全性要求:

  1. 必須使用EC演算法
  2. 金鑰密碼要”大小寫字母/數字/ 特殊字 符,至少兩種的組合,長度大於等於 8

如果簽名檔案構建的時間比較早,這兩個要求都不符合的話,華為側提供瞭如下解決方案:

1、可以使用原Android簽名檔案單獨配置shell Apk簽名

apply plugin: 'com.huawei.ohos.hap'
ohos {
    ... 
  legacyApkOptions {
    ... 
    signConfig {
        storeFile file("..\legacyApkJks.jks") // 單獨配置的 shell apk 簽名材料
    }
    ... 
  }
}

2、使用keytool命令列生成p12檔案和csr檔案,但要求別名和祕鑰跟原Android簽名保持一致,並且使用EC演算法

//生成p12
keytool -genkey -alias [keyname] -keystore [p12.file] -storetype pkcs12 -keyalg EC -keypass [password] -storepass [password]

//生成csr
keytool -certreq -alias [keyname] -keystore [p12.file] -storetype pkcs12 -file [csr.file]

申請下來cer和p7b檔案(需要單獨申請除錯和釋出證照)後,就可以在開發工具中配置簽名檔案了(更多配置詳情也閱覽華為配置簽名幫助文件 https://developer.harmonyos.c...)。

然後通過開發工具DevEco Studio中build -> Build Apps編譯得到產物APP。

工程結構概述:

混合包產物分析

經過上面的一系列流程,就可以生成一個供鴻蒙執行的混合包了。

由於是釋出證照籤名,這個混合包實際上是不能直接手動安裝到Harmony OS上,還需要經過華為平臺側(需要聯絡華為側介面人)簽名,提供轉換之後的安裝包供優酷方面測試使用。

測試完畢之後,可以直接拿這個混合包上架到華為的鴻蒙應用市場。

鴻蒙版本發版經驗總結

  • 鴻蒙混合包只有64位包;
  • 鴻蒙混合包在鴻蒙市場發版節奏、版本號等最好是跟原安卓發版節奏、版本號等保持一致,不然需要特殊考慮鴻蒙版本的資料定投問題;
  • apk和hap在app中實際是物理區分,打包app的時候並不會把apk重新編譯,所以如果apk和hap存在同名的類(因為都是java類),根據雙親委派機制,在執行時將會出現問題;
  • 如果原安卓應用包含通訊錄、撥打電話許可權,在華為平臺申請p7b檔案時一定需要勾選申請使用受限許可權,如下圖:

最後,下週《優酷鴻蒙開發實踐》系列第三篇技術文章,我們將以優酷播放中心的技術儲備為切入點,結合鴻蒙系統的映象和流轉特性,詳細介紹普通流轉、自由視角和zoom 等核心能力在鴻蒙上的實踐之路。

感謝關注【阿里巴巴移動技術】,我們下篇技術實踐再見。

關注我們,每週 3 篇移動技術實踐&乾貨給你思考!

相關文章