Android 應用安全機制實現方案探究

語言: CN / TW / HK

一、為什麼要做安全加固?

當我們開發好 Android App 準備上架應用市場時,應用市場會要求上架的 App 做加固處理,這是為什麼呢 ?

首先,來看下騰訊開放平臺官方的解釋說明。

  • 若應用不做任何安全防護,極易被病毒植入、廣告替換、支付渠道篡改、釣魚、資訊劫持等,嚴重侵害開發者的利益。

  • App 加固後,可以對應用進行安全防護,防止應用分發後,被反編譯、除錯、盜版、破解、二次打包等威脅,維護開發者的利益。

當然,除了應用加固外,還有其它的安全解決方案如:安全檢測(漏洞掃描)、渠道監控(正盜版分發情況監控)和安全 SDK(專業場景下的安全解決方案)等。

簡單來說就是,如果你不希望自己參與開發的 App 出現以下問題,是免費為別人寫的,那就做 APP 加固吧。

  • 應用程式被破解

  • 核心程式碼被竊取

  • 惡意程式碼注入

  • 核心資料洩露

  • 安全檢測未合規

二、如何為 App 應用加固?

目前市面上主流的加固方式有 360 加固保 騰訊雲樂固 梆梆加固 網易易頓 、頂象等等...這些加固平臺工作流程基本都是 APK 加固、APP 簽名

網易易頓加固截圖資訊:

頂象加固截圖資訊:

騰訊雲加固截圖資訊(果然白嫖的不香~):

加固後效果如下:

三、APP 簽名

除了對 APP 進行加固操作,還需要進行簽名。APP 通過對 Apk 進行簽名,開發者可以證明對 Apk 的所有權和控制權,可用於安裝和更新其應用。而在 Android 裝置上安裝 Apk ,如果是一個沒有被簽名的 Apk,則會被拒絕安裝。

在安裝 Apk 的時候, 軟體包管理器 也會驗證 Apk 是否已經被正確簽名,並且通過 簽名證書資料摘要 驗證是否合法沒有被篡改。只有確認安全無篡改的情況下,才允許安裝在裝置上。

簡單來說,APK 簽名主要作用有兩個:

  • 證明 APK 的所有者;

  • 允許 Android 市場和裝置校驗 APK 的正確性。

簽名的話,一般使用通用簽名工具 ApkSigner

ApkSigner 是 jar 包形式的簽名工具,較傳統工具簽名快很多,適用於 Win/Mac/Linux 環境。

點選下載

3.1 使用說明

  1. 解壓下載包

  2. 命令列執行(需要 jdk 環境)

   java -jar ApkSigner.jar [-appname test] -keystore keystorePath -alias alias [-pswd password] [-aliaspswd aliasPassword] apkPath(or directory)

複製程式碼

注意:warning::簽名之後,如果需要進行對齊操作,請呼叫命令: zipalign -f 4 in.apk out.apkzipalign 這個程式在 android sdk 有提供。

(可選) android7.0 及之後的 apk,可以採用 v2 簽名,提高 apk 安裝速度。但是為了相容 android7.0 之前的系統,也需要進行 v1 簽名,且需要先進行 v1 簽名,apk 位元組對齊(可選),再進 行v2 簽名。具體步驟命令如下:

  1. java -jar ApkSigner.jar [-appname test] -keystore keystorePath -alias alias [-pswd password] [-aliaspswd aliasPassword] -v1 true -v2 false in.apk

  2. zipalign -c -f [alignmentSize] in.apk out.apk (可選)

  3. java -jar ApkSigner.jar [-appname test] -keystore keystorePath -alias alias [-pswd password] [-aliaspswd aliasPassword] -v1 false -v2 true out.apk

其中, option 引數說明:

  • appname 待簽名的應用程式名,可選,但建議不同的 APP 填上對應的 app 名(可以為中文),有助於【加速】;

  • keystore 後跟 .keystore 簽名檔案;

  • alias 後跟簽名別名;

  • pswd 後跟對應簽名的密碼,例如這裡是:android 可選,如果不填,則簽名的時候需要手動輸入;

  • aliaspswd 對應別名 alias 的密碼,如果沒有則預設使用 keystorePassword ,最後跟待簽名的 APK 路徑或者目錄路徑 ,如果跟的是目錄則是批量簽名;

  • v1 true(預設)表示使用 v1 簽名模式,false 表示不使用;

  • v2 true 表示使用 v2 簽名模式,false(預設)表示不適用;

3.2 V1、V2、V3、V4 簽名方案

Android 目前支援以下四種應用簽名方案:

  • v1 方案:基於 JAR 簽名。

  • v2 方案:APK 簽名方案 v2(在 Android 7.0 中引入)

  • v3 方案:APK 簽名方案 v3(在 Android 9 中引入)

  • v4 方案:APK 簽名方案 v4(在 Android 11 中引入)

其中,v1 到 v2 是顛覆性的,為了解決 JAR 簽名方案的安全性問題,而到了 v3 方案,其實結構上並沒有太大的調整,可以理解為 v2 簽名方案的升級版,有一些資料也把它稱之為 v2+ 方案。

3.2.1 v1 簽名

Android 7.0 (即 Android N,Android Api 24 ) 以下的版本,只能使用舊簽名方案,也就是 v1 簽名。

v1 簽名使用 JDKjarsigner 工具,對 zip 壓縮包的每個檔案進行驗證,簽名後仍可對壓縮包進行修改、移動、重新壓縮檔案。

V1 簽名的機制主要就在 META-INF 目錄下的三個檔案, MANIFEST.MFCERT.SFCERT.RSA ,他們都是 V1 簽名的產物。

在 V1 簽名方案中,並不會保護 APK 內的所有檔案,會存在一些例外部分,即便被修改也不會導致簽名失效。

例如:ZIP 元資料。同時,v1 方案對 APK 內部被保護的原始檔案,是 單獨 進行計算資料摘要的,所以在驗證時,需要先解壓再驗證,導致安裝時會 花費更多的時間消耗更多的記憶體 。例如 v1 方案中籤渠道的方式就是利用了此特性,將渠道資訊寫入 META-INF 檔案中,這不會破壞 v1 簽名。

缺點是: 不安全、速度慢

為了解決這些問題,Android 7.0 中引入了 APK 簽名方案 v2。

3.2.2 v2 簽名

Android 7.0 開始,Google 新增了 v2 簽名方案。

v2 簽名使用 Google 自帶的 apksigner 工具,對 zip 壓縮包的整個檔案進行驗證,簽名後不能修改壓縮包,包括 zipalgin

如果你對 v2 簽名的 apk 解壓,沒有發現簽名檔案,重新壓縮後 v2 簽名失效,這說明 v2 簽名是對整個 Apk 進行簽名驗證。

v2 簽名是一種 全檔案簽名方案 ,該方案能夠發現對 APK 的受保護部分進行的所有更改,從而有助於加快驗證速度並增強 完整性保證

使用 APK 簽名方案 v2 進行簽名時,會在 APK 檔案中插入一個 APK 簽名分塊,該分塊位於「 ZIP 中央目錄 」部分之前並緊鄰該部分。在「 APK 簽名分塊 」內,v2 簽名和簽名者身份資訊會儲存在 APK 簽名方案 v2 分塊 中。

上圖是簽名前後,APK 檔案結構的對比。可以看到在 v2 已簽名的 APK 中,包含了 4 個部分:

  • ZIP 條目的內容

  • APK 簽名分塊(APK Signing Block)

  • ZIP 中央目錄

  • ZIP 中央目錄結尾

在驗證期間,v2+ 方案會將 APK 檔案視為 blob ,並對整個檔案進行簽名檢查。對 APK 進行的任何修改(包括對 ZIP 元資料進行的修改)都會使 APK 簽名作廢。這種形式的 APK 驗證不僅速度要快得多,而且能夠發現更多種未經授權的修改。

新的簽名格式向後相容,因此,使用這種新格式簽名的 APK 可在更低版本的 Android 裝置上進行安裝(會直接忽略新增到 APK 的額外資料),但 前提是這些 APK 還帶有 v1 簽名。

從安全的角度 v2 會比 v1 更安全,v2 簽名是驗證整個打包後的 APK 檔案,所以對其 APK 檔案做「 任何 」改動都會破壞簽名。注意這裡的任何是帶引號的,V2 簽名的簽名塊其實是一個 K-V 的結構,可以向其中插入一些簡單的資料而不破壞 v2 簽名,這就是 v2 方案下,多渠道的方案思路。

缺點是: 無法解決簽名過期更換籤名的問題

3.2.3 v2 簽名相對 v1 簽名的優點

  • 因為不能修改壓縮包,所以 v2 簽名會更安全。

  • v2 簽名是對整個 Apk 進行簽名驗證,不需要解壓驗證,所以簽名驗證的時間會更短。

3.2.4 v3 簽名

v2 方案解決了 安全問題 以及安裝時驗證的 效率問題 ,但是它並沒有解決 更換籤名問題

Android 9.0 中引入了新的簽名方式,它的格式大體和 v2 類似,在 v2 插入的簽名塊( Apk Signature Block v2 )中,又添加了一個新快(Attr 塊)。

在這個新塊中,會記錄之前的簽名信息以及新的簽名信息,以 金鑰轉輪 的方案,來做簽名的替換和升級。這意味著,只要舊簽名證書在手,就可以通過它在新的 APK 檔案中,更改簽名。

V3 簽名新增的新塊( attr )儲存了所有的簽名信息,由更小的 Level 塊,以連結串列的形式儲存。

其中每個節點都包含用於為之前版本的應用簽名的簽名證書,最舊的簽名證書對應根節點,系統會讓每個節點中的證書為列表中下一個證書籤名,從而為每個新金鑰提供證據來證明它應該像舊金鑰一樣可信。

這個過程有點類似 CA 證書的證明過程,已安裝的 App 的舊簽名,確保覆蓋安裝的 APK 的新簽名正確,將信任傳遞下去。

3.2.5 v4 簽名

在傳統的應用安裝方案中,開發者通過 ADB( Android Debug Bridge )以有線或無線的方式與終端使用者連線,或者使用者從軟體商店直接下載,然而該方案需要使用者等待完整的安裝包傳輸結束後才能啟動安裝,在這期間產生了不良的使用者體驗。

增量安裝技術是一種 流式安裝方案 :一旦安裝包的核心檔案傳輸完成便可啟動應用。流式安裝意味著允許優先傳輸核心資料以啟動應用,並在後臺流式傳輸剩餘資料。

在Android 11中,Google在核心中實現了增量檔案系統用於對增量安裝的支援。

這使得 Android os 可以通過 ADB 流式傳輸 APK。同時,Android 11 為了適應增量安裝,添加了新的 v4 簽名方案。

此方案不改變前代簽名方案而是建立一種新的簽名:基於 APK 所有位元組資料計算出 Merkle 雜湊樹 ,並將 Merkle 樹的根雜湊、鹽值作為簽名資料進行包完整性驗證。新的簽名資料儲存在 .idsig 檔案中並且在進行增量安裝前必須為 APK 建立對應的 v4 簽名檔案。

官方文件:v4簽名

3.2.6 總結

  • v1 簽名實際上就是 JAR 簽名的方案,它不會保護 APK 內的所有問題,存在安全和效率問題;

  • v2 簽名是一種 全檔案簽名方案 ,增加了 APK 簽名塊( APK Signing Block ),但仍無法解決更換籤名的問題;

  • v3 簽名是 v2 的升級版,也被稱為 v2+。在 V2 插入的簽名塊( Apk Signature Block V2 )中,又添加了一個新快(Attr 塊),它使用連結串列儲存了所有的簽名信息,驗證時就像 CA 證書的證明過程。

  • v4 簽名是為了增量安裝技術而產生的一種新的簽名方案。

3.3 jarsigner 與 apksigner

3.3.1 jarsigner

jarsignerJDK 提供的針對 jar 包簽名的工具,如果你本地已經安裝了 Java 環境,會自帶 jarsigner

比如我的 jarsigner 工具的位置在

/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/bin/jarsigner

複製程式碼

效果圖如下:

3.3.2 apksigner

apksignerGoogle 官方提供的針對 Android Apk 簽名和驗證的專用工具,位於 Android SDK / build-tools / SDK 版本 / apksigner

以我本地的 Android SDK 30.0.2 版本為例, apksigner 工具的位置在 /Users/suxing/Library/Android/sdk/build-tools/30.0.2/apksigner

效果圖如下:

如果你用的是 Android Studio 或者 IDEA ,安裝這兩個編輯器時會自動下載 Android SDK ,所以 apksigner 工具也不需要另外安裝。

不過,無論是 apk 包還是 jar 包,其本質都是 zip 格式的壓縮包,如果只針對 v1 簽名的話,兩者的簽名過程其實差不多。

apksigner 工具默認同時使用 v1v2 簽名,以相容 Android 7 以下的系統版本。

為方便應用 apksigner 簽名,可將 apksigner 徑配置到系統環境變數 path。實現步驟如下:

  1. cd ~

  2. open -e .bash_profile

  3. source .bash_profile

.bash_profile 檔案內容如下:

source ~/.bashrc
# Git branch in prompt.
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\[email protected]\h \W\[\033[32m\]\$(parse_git_branch)\[\033[00m\] $ "
source ~/.bashrc
export ANDROID_HOME=/Users/ccms-m-03/Library/Android/sdkexport PATH=${PATH}:${ANDROID_HOME}/toolsexport PATH=${PATH}:${ANDROID_HOME}/platform-tools
export AAPT_HOME=/Users/ccms-m-03/Library/Android/sdk/build-tools/30.0.3export PATH=$PATH:$AAPT_HOME
source ~/.bashrc

複製程式碼

apksigner 通過以下指令實現 apk 簽名。

apksigner sign --ks android.jks --ks-key-alias android --out signed.apk unsigned.apk

複製程式碼

  • --ks .jks 檔案路勁

  • --ks-key-alias 簽名檔案別名

  • --out 輸出簽名後的目標路徑

  • unsigned.apk 未簽名的原始 apk 檔案路徑

為了避免路徑過長,書寫錯誤的、問題,建議將加固包 jks 檔案放置在同一目錄。

其實從檔案的大小我們就可以看到有變化,但是還得驗證是否簽名成功,用以下指令校驗:

 apksigner verify --verbose signed.apk

複製程式碼

簽名成功如下圖:

沒有簽名如下提示:

簽名後如果包能正確安裝到手機(無需執行)則沒有問題,如果安裝失敗請用命令安裝: adb install apkfile 查看出錯資訊。

3.3.3 簽名檔案 jks 與 keystore 格式

  • .jks 是在 android studio 裡面生成的簽名證書。

  • .keystoreeclipse 裡面生成的簽名證書。

兩者在使用方式上沒有什麼區別,但是在演算法上有一點區別。

3.3.3.1 jks 轉 keystore

在應用 apksigner 簽名工具進行 APK 簽名時,發現只支援 .keystore 格式的簽名檔案,需要把 .jks 簽名格式轉化為 .keystore 格式。

直接用命令列轉換,先生成 .p12 檔案,用 .p12 生成 .keystore

keytool -importkeystore -srckeystore test.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore test.p12

複製程式碼

keytool -v -importkeystore -srckeystore test.p12 -srcstoretype PKCS12 -destkeystore test.keystore -deststoretype JKS

複製程式碼

轉換後,會看到如下提示資訊。可以通過提示的命令列

keytool -importkeystore -srckeystore cicc-keystore.keystore -destkeystore cicc-keystore.keystore deststoretype pkcs12

複製程式碼

按照指定行業標準格式進行轉換。

Warning: JKS 金鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystorecicc-keystore.keystore -destkeystore cicc-keystore.keystore-deststoretype pkcs12" 遷移到行業標準格式 PKCS12。

現在 test.keystore 的簽名應該與 test.jks 的簽名信息是一樣的了。

可以通過以下命令來驗證:

keytool -v -list -keystore test.keystore

複製程式碼

3.3.3.1 keystore 轉 jks

同理, .keystore 也可以轉 .jks ,轉換命令如下:

keytool -importkeystore -srckeystore test.keystore -srcstoretype JKS -deststoretype PKCS12 -destkeystore test.p12

複製程式碼

keytool -v -importkeystore -srckeystore test.p12 -srcstoretype PKCS12 -destkeystore test.jks -deststoretype JKS

複製程式碼

3.4 簽名驗證

應用簽名工具對 APP 做好籤名後,如何驗證簽名的正確性,或者是給你一個 apk,如何驗證該 apk 是否完成了簽名操作。

3.4.1 檢視 apk 簽名

應用 keytool 工具可實現檔案簽名驗證。

keytool -printcert -jarfile ./weixin806android1900_arm64.apk 

複製程式碼

apk 為已簽名,則會顯示以下資訊:

apk 未簽名,則會提示 不是已簽名的 jar 檔案

拓展閱讀: KeyTool 是 Java 中的數字證書管理工具,用於數字證書的申請、匯入、匯出和撤銷等證書管理操作,位於 <JAVA_HOME>\bin\keytool.exe 。要獲得數字證書,我們需要使用數字證書管理工具(如 KeyToolOpenSSL )構建 CSR ( Certificate Signing Request數字證書籤發申請 ),交由 CA 機構簽發,形成最終的數字證書。

3.4.2 檢視簽名檔案

同樣使用 keytool 工具檢視 xxx.keystore 或者 xxx.jks ,注意檢視自己的簽名檔案則需要密碼輸入才能檢視。根據以下命令輸出資訊,通過對比 apk 簽名輸出的 MD5sha 資訊是否一致,一致則代表簽名成功。

keytool -v -list -keystore xxx.jks 

複製程式碼

四、APP 資訊校驗

APP 組好包之後,如何檢視包資訊?

4.1 APK 資訊檢視

首先找到 aapt 工具,在 Android SDK 資料夾下的 build-tools 包裡應用 aapt 命令便可實現檢視 Android APK 資訊。

或者將 aapt 命令新增到環境變數。

然後,通過 aapt 命令便可檢視 apk 包的 packageName、versionCode、applicationLabel、launcherActivity、permission 等各種詳細資訊

先 cd 到 apk 所在目錄,然後執行以下命令 :

檢視 apk 的基本配置資訊

aapt dump badging test.apk

複製程式碼

檢視 apk 的許可權

aapt dump permissions test.apk

複製程式碼

檢視 apk 的資源列表

aapt dump resources test.apk

複製程式碼

一般都會輸出很多的資訊,如要全部檢視,請用下面這個命令:

aapt dump resources test.apk   > test.txt

複製程式碼

這樣會把所有的資訊通過重定向符" > "輸出到 test.txt 檔案中,然後再開啟該檔案即可檢視。

檢視 apk 配置資訊

aapt dump configurations test.apk

複製程式碼

檢視指定 apk 的指定 xml 檔案,以樹形結構輸出的 xml 資訊

aapt dump xmltree test.apk res/***.xml

複製程式碼

輸出 xml 檔案中所有的字串資訊

aapt dump xmlstrings test.apk res/***.xml

複製程式碼

4.2 versionCode 與 versionName

4.2.1 versionCode

主要是用於版本升級所用,是 Integer 型別的,第一個版本定義為 1,以後遞增,這樣只要判斷該值就能確定是否需要升級,該值不顯示給使用者。

不要將 versionCode 設定的太大,最好不要超過 Integer 的取值範圍,一般大發布第一個應用到市場的時候,版本取值為 1( versionCode=1 ),這也是目前典型和普遍的做法。

每次釋出更新版本時可以遞增 versionCode 的值,一個新版本的應用的 versionCode 不能小於之前舊版本的 versionCode 值,否則進行替換更新升級時會出錯,系統提示無法安裝。這也不是強制的,只是正式釋出應用時,建議必須考慮的問題。

注意:warning:: 同一個 APP 低版本是不能直接覆蓋安裝手機中已存在的高版本應用(通過版本號( versionCode )來判斷)。

4.2.2 versionName

這個是我們常說的版本號,這是一個值為 String 型別的屬性,由三部分組成 <major>.<minor>.<point>VersionCode 是方便程式開發者執行和維護 Application 而設定的一個有效值。 versionName 是一個版本的描述,給使用者看的,也是使用者放在各個第三方平臺上提供給使用者看的一個版本名,可以說是對 VersionCode 的解釋和描述。其中,

  • major 是主版本號,一般在軟體有重大升級時增長;

  • minor 是次版本號,一般在軟體有新功能時增長;

  • maintenance 是維護版本,一般在軟體有主要的問題修復後增長;

4.3 ipa 資訊檢視

解壓 IPA 安裝包檔案,然後通過開啟 APP 的資訊檔案: info.plist 來檢視 名稱Bundle ID版本 等基本資訊,如果要檢視證書檔名稱,那就需要通過命令列工具:security 來檢視描述檔案:embedded.mobileprovision。

五、CPU 型別配置

Android 平臺配置 CPU 型別針對的是為了提高執行效率,使用 C/C++ 語言開發生成的 so 庫,需要為各 cpu 型別平臺單獨編譯生成對應指令的 so 庫。 Java 語言開發的程式碼執行在虛擬機器中,基於虛擬機器跨平臺特性,由虛擬機器適配 CPU 型別,不涉及到此問題。

HBuilder/HBuilderX 中使用 so 庫的功能(模組)如下:

  • Audio (錄音):支援 mp3 格式;

  • Geolocation (定位):百度;

  • LivePush (直播推流);

  • Maps (地圖):高德、百度;

  • OAuth (登入鑑權):新浪微博;

  • Push (訊息推送):個推、UniPush;

  • Share (分享):新浪微博;

  • Speech (語音輸入):百度,注意:訊飛不支援 64 位;

  • Weex (原生渲染): uni-app (自定義元件模式、nvue 頁面), 注意: HBuilderX2.1.5 及以上版本支援;

注意:warning::

  • HBuilderX2.7.0+ 調整 雲端打包預設不再包含 x86 CPU 型別庫,減少 apk 包體積詳情;

  • HBuilderX2.1.5+ 開始支援 Android 平臺的新增適配 64 位 CPU 型別,雲端打包支援配置 App 支援的 CPU 型別,滿足 Google Play 從 2019 年 8 月 1 日起上傳的 App 必需支援 64 位 CPU 的要求。

5.1 CPU 型別

HBulderX 已適配支援以下主流 CPU 型別:

  • armeabi-v7a第 7 代及以上的 ARM 處理器(ARM32 位),市面上大多數手機使用此 CPU 型別。

  • arm64-v8a第 8 代、64 位 ARM 處理器(ARM64 位),最近兩年新發的裝置使用此 CPU 型別,可以相容使用 armeabi-v7a 的 so 庫。

x86 少部分平板使用 x86,AS 模擬器中選了 intel x86 時使用 x86 處理器,以及其它常用三方模擬器通常使用 x86。

注意:warning::不勾選 x86 在模擬器上可能無法正常執行,以下是常見模擬器是否需要包含 x86 的情況:

  • 雷電模擬器: 3.x 必須包含 x86,否則無法正常執行;4.x 無需包含 x86;

  • 夜神模擬器: 必須包含 x86,否則無法正常執行;

  • MuMu 模擬器: 無需包含 x86;

  • 逍遙模擬器: 無需包含 x86;

  • BlueStacks(藍疊模擬器): 無需包含 x86;

  • 騰訊模擬器(手遊助手): 必須包含 x86,否則無法正常執行;

  • 其它模擬器: 未測試驗證,建議包含 x86,確保在模擬器正常執行;

5.2 配置支援的 CPU 型別

5.2.1 視覺化介面配置

開啟專案的 manifest.json 檔案,在 “App常用其它設定” -> “Android設定” -> “支援CPU型別” 項中勾選需要支援的 CPU 型別:

5.2.2 原始碼檢視配置

開啟專案的 manifest.json 檔案,切換到“原始碼檢視”,根據專案型別進行配置。

5.2.2.1 uni-app 專案

"app-plus"->"distribute"->"android" 節點的 abiFilters 屬性配置支援的 CPU 型別,示例如下:

  "app-plus": {    "distribute": {      "android": {        "abiFilters": [          "armeabi-v7a",          "arm64-v8a"        ]        //...      },      //...    },    //...  },  //..

複製程式碼

4.2.2.2 離線打包配置

使用 Android studio 開啟 Android 原生專案,開啟對應專案的 build.gradle 檔案。 在 Android -> defaultConfig 下新增支援的 CPU 型別,如下示例:

defaultConfig{  ndk {            abiFilters 'arm64-v8a','armeabi-v7a'        }}

複製程式碼

注意:離線打包僅支援 arm64-v8a、armeabi-v7a、x86 三種類型,建議根據自己需求選擇打包的

5.3 CPU 型別

5.3.1 CPU 型別選擇建議

ARM64 位( arm64-v8a )CPU 可以相容 ARM32 的指令,也就是說只選擇 armeabi-v7a 型別的 so 庫也可以在 64 位手機上執行,只是沒有完全發揮 CPU 的效能。 選擇支援的 CPU 型別時請參考以下建議:

  • 如果不在意 apk 大小,三種 CPU 型別都勾選;

  • 如果在意 apk 大小,選擇 ARM32 位即可(幾乎在所有 ARM 指令的所有裝置上都可正常執行);

  • 如果要相容一些平板和模擬器,選擇 ARM32 位和 X86 不是所有模擬都僅支援 x86 指令,如雷電(4.x)、MuMu 等模擬器也是支援 ARM 指令。

5.3.2 檢視 apk 支援的 CPU 型別

使用解壓工具開啟 apk,在 lib 目錄下可以檢視到支援的 CPU 型別,如下圖所示:

5.3.3 常見問題

提交 Google Play 時要求支援 64 位,建議選擇" armeabi-v7a "和" arm64-v8a "兩個即可,也可以只選擇" arm64-v8a "。

注意:warning::不要勾選"x86"!

如果打包選擇的 CPU 型別與裝置不相容,會導致無法正常安裝。 通過 adb 命令安裝通常會提示如下錯誤:

Performing Streamed Installadb: failed to install android_debug.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]

複製程式碼

使用 Android Studio 自帶的 x86 模擬器,將不包含 x86 cpu 型別的 apk 拖到模擬器安裝時會彈出如下提示框:

目前市面上常見的手機都是使用 ARM 處理器 ,很少有裝置使用 x86 處理器 ,因此從 HBuilderX2.7.0 開始雲端打包調整為預設不再包含 x86 的 CPU 型別,減少 apk 包大小:

  • uni-app 專案基礎功能 apk 減少 5M+,使用的三方 SDK 及 uni 原生外掛越多,減少的包尺寸越大,具體值取決於其包含的 x86 型別的 so 庫大小;

  • 5+App、Wap2App 專案 基礎功能 apk 減少 100K+,如果使用的三方 SDK 中存在 so 庫則減少的尺寸較大,具體值取決於其包含的 x86 型別的 so 庫大小

注意:warning::大多數模擬器(如夜神)必須包含 x86,否則應用啟動時可能會白屏,請進行配置!

六、拓展閱讀