Android - 为不同的处理器架构构建单独的 APK [英] Android - build separate APKs for different processor architectures

查看:25
本文介绍了Android - 为不同的处理器架构构建单独的 APK的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种简单的方法可以使用旧的 ANT 或新的 Gradle 构建过程为不同的处理器架构为 Android 构建单独的 APK 文件?我这样做的方法是构建一个包含所有支持的本机库的胖"APK,然后按照我解释的那样将它们拆分为单独的 APK这里.不过,似乎应该有更直接的方法来做到这一点...

Is there an easy way to build separate APK files for Android for different processor architectures, with the old ANT or the new Gradle build process? My way of doing this is to build one "fat" APK with all supported native libraries included, and then splitting them into separate APK as I explained here. However, it seem that there should be a more direct method of doing this...

推荐答案

我决定重新发布我的其他地方的答案 在这里,所有这些都在一页上,以便于访问.如果这违反 SO 政策,请告诉我并从此处删除此帖子.

I decided to re-post my answer from elsewhere here, so that all of this is on one page for easy access. If this is against SO policies, please tell me and delete this post from here.

这是我关于如何为每个支持的处理器架构创建单独的 APK 文件的想法:

Here is my idea on how to create separate APK files for each supported processor architecture:

  1. 使用您使用的任何工具构建一个胖"APK,其中包含您支持的所有本机代码库,例如armeabi、armeabi-v7a、x86 和 mips.我将其称为原始"APK 文件.

  1. Build one "fat" APK with any tools you use, containing all native code libraries you support, e.g. armeabi, armeabi-v7a, x86 and mips. I'll call it the 'original' APK file.

将您的原始 APK 解压缩到一个空文件夹中,使用任何 zip/unzip 实用程序,最好使用命令行工具,以便您稍后可以使用 shell 脚本或批处理文件将其自动化.实际上,正如我下面发布的示例批处理脚本所示,我只是使用命令行压缩/解压缩工具来直接操作 APK,而不是完全解压缩它们,但效果是一样的.

Unzip your original APK into an empty folder, with any zip/unzip utility, best use command line tools, so that you could automate it with a shell script or batch file later. Actually, as my sample batch script posted below shows, I just use command line zip/unzip tools to manipulate APKs directly, instead of unzipping them fully, but the effect is the same.

在原APK解压到的文件夹(或原.apk/.zip)中,删除META-INF子文件夹(这里包含签名,我们需要重新签名APK全部修改后,必须删除原来的META-INF).

In the folder where original APK was uncompressed to (or in the original .apk/.zip), delete META-INF sub-folder (this contains the signatures, we'll need to re-sign the APK after all the modifications, so the original META-INF must be deleted).

更改为 lib 子文件夹,并删除新 APK 文件中不需要的任何处理器架构的子文件夹.例如,仅保留x86"子文件夹以制作适用于 Intel Atom 处理器的 APK.

Change to lib sub-folder, and delete the sub-folders for any processor architectures you don't want in the new APK file. For example, leave only 'x86' sub-folder to make an APK for Intel Atom processors.

重要提示:针对不同架构的每个 APK,在 AndroidManifest.xml 中必须有不同的versionCode"编号,以及版本代码,例如armeabi-v7a 必须比 armeabi 略高(在此处阅读谷歌创建多个 APK 的说明:http://developer.android.com/google/play/publishing/multiple-apks.html).不幸的是,清单文件在 APK 中采用编译后的二进制形式.我们需要一个特殊的工具来修改那里的 versionCode.见下文.

Important: each APK for a different architecture, must have a different 'versionCode' number in AndroidManifest.xml, and the version code for e.g. armeabi-v7a must be slightly higher than the one for armeabi (read Google directions for creating multiple APKs here: http://developer.android.com/google/play/publishing/multiple-apks.html ). Unfortunately, the manifest file is in a compiled binary form inside the APK. We need a special tool for modifying the versionCode there. See below.

使用新版本代码修改清单并删除不必要的目录和文件后,重新压缩、签名和对齐较小的 APK(使用 Android SDK 中的 jarsigner 和 zipalign 工具).

Once the manifest is modified with a new version code, and unnecessary directories and files deleted, re-zip, sign and align your smaller APK (use jarsigner and zipalign tools from Android SDK).

为您需要支持的所有其他架构重复此过程,创建版本代码略有不同(但版本名称相同)的较小 APK 文件.

Repeat the process for all other architectures you need to support, creating smaller APK files with slightly different version codes (but the same version name).

唯一未解决的问题是在二进制清单文件中修改versionCode"的方法.很长一段时间我都找不到解决方案,所以最后不得不坐下来编写自己的代码来做到这一点.作为起点,我选择了 Prasanta Paul 的 APKExtractor,http://code.google.com/p/apk-extractor/,用 Java 编写.我是老派,仍然更喜欢 C++,所以我用 C++ 编写的小实用程序aminc"现在在 GitHub 上:

The only outstanding issue is the way to modify ‘versionCode’ in binary manifest file. I could not find a solution for this for a long time, so finally had to sit down and crank my own code to do this. As the starting point, I took APKExtractor by Prasanta Paul, http://code.google.com/p/apk-extractor/, written in Java. I’m the old school and still more comfortable with C++, so my little utility program 'aminc' written in C++ is now on GitHub at:

https://github.com/gregko/aminc

我在那里发布了整个 Visual Studio 2012 解决方案,但整个程序是一个 .cpp 文件,可能可以在任何平台上编译.这是一个示例 Windows 批处理脚本文件,我用来将名为 atVoice.apk 的胖"apk 拆分为 4 个更小的文件,分别名为 atVoice_armeabi.apk、atVoice_armeabi-v7a.apk、atVoice_x86.apk 和 atVoice_mips.apk.我实际上将这些文件提交到 Google Play(在 https 上查看我的应用程序://play.google.com/store/apps/details?id=com.hyperionics.avar) 并且一切正常:

I posted the entire Visual Studio 2012 solution there, but the whole program is a single .cpp file which probably can be compiled on any platform. And here is a sample Windows batch script file I use to split my "fat" apk named atVoice.apk into 4 smaller files named atVoice_armeabi.apk, atVoice_armeabi-v7a.apk, atVoice_x86.apk and atVoice_mips.apk. I actually submit these files to Google Play (see my app at https://play.google.com/store/apps/details?id=com.hyperionics.avar) and all works perfectly:

@echo off
REM    My "fat" apk is named atVoice.apk. Change below to whatever or set from %1
set apkfile=atVoice
del *.apk

REM    My tools build atVoice-release.apk in bin project sub-dir. 
REM    Copy it herefor splitting.
copy ..\bin\%apkfile%-release.apk %apkfile%.apk

zip -d %apkfile%.apk META-INF/*

REM ------------------- armeabi ------------------------
unzip %apkfile%.apk AndroidManifest.xml
copy/y %apkfile%.apk %apkfile%.zip
zip -d %apkfile%.zip lib/armeabi-v7a/* lib/x86/* lib/mips/*
aminc AndroidManifest.xml 1
zip -f %apkfile%.zip
ren %apkfile%.zip %apkfile%_armeabi.apk
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore d:\users\greg\.android\Hyperionics.keystore -storepass MyPass %apkfile%_armeabi.apk MyKeyName
zipalign 4 %apkfile%_armeabi.apk %apkfile%_armeabi-aligned.apk
del %apkfile%_armeabi.apk
ren %apkfile%_armeabi-aligned.apk %apkfile%_armeabi.apk

REM ------------------- armeabi-v7a ---------------------
copy/y %apkfile%.apk %apkfile%.zip
zip -d %apkfile%.zip lib/armeabi/* lib/x86/* lib/mips/*
aminc AndroidManifest.xml 1
zip -f %apkfile%.zip
ren %apkfile%.zip %apkfile%_armeabi-v7a.apk
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore d:\users\greg\.android\Hyperionics.keystore -storepass MyPass %apkfile%_armeabi-v7a.apk MyKeyName
zipalign 4 %apkfile%_armeabi-v7a.apk %apkfile%_armeabi-v7a-aligned.apk
del %apkfile%_armeabi-v7a.apk
ren %apkfile%_armeabi-v7a-aligned.apk %apkfile%_armeabi-v7a.apk

REM ------------------- x86 ---------------------
copy/y %apkfile%.apk %apkfile%.zip
zip -d %apkfile%.zip lib/armeabi/* lib/armeabi-v7a/* lib/mips/*
aminc AndroidManifest.xml 9
zip -f %apkfile%.zip
ren %apkfile%.zip %apkfile%_x86.apk
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore d:\users\greg\.android\Hyperionics.keystore -storepass MyPass %apkfile%_x86.apk MyKeyName
zipalign 4 %apkfile%_x86.apk %apkfile%_x86-aligned.apk
del %apkfile%_x86.apk
ren %apkfile%_x86-aligned.apk %apkfile%_x86.apk

REM ------------------- MIPS ---------------------
copy/y %apkfile%.apk %apkfile%.zip
zip -d %apkfile%.zip lib/armeabi/* lib/armeabi-v7a/* lib/x86/*
aminc AndroidManifest.xml 10
zip -f %apkfile%.zip
ren %apkfile%.zip %apkfile%_mips.apk
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore d:\users\greg\.android\Hyperionics.keystore -storepass MyPass %apkfile%_mips.apk MyKeyName
zipalign 4 %apkfile%_mips.apk %apkfile%_mips-aligned.apk
del %apkfile%_mips.apk
ren %apkfile%_mips-aligned.apk %apkfile%_mips.apk


del AndroidManifest.xml
del %apkfile%.apk
:done

额外的保护措施

我在 Google Play 开发者控制台收到一些错误报告,指出找不到本机方法.这很可能是由用户安装错误的 APK 引起的,例如ARM 设备上的 Intel 或 MIPS APK.向我的应用程序添加了额外的代码,根据 Build.CPU_ABI 检查 VersionCode 编号,然后在不匹配的情况下显示错误消息,要求用户从 Google Play(或我自己的网站,在那里我发布了胖"APK)重新安装) 在这种情况下.

Additional safeguards

I get a few error reports at Google Play developer console, stating that a native method could not be found. Most probably this is caused by the user installing a wrong APK, e.g. Intel or MIPS APK on an ARM device. Added extra code to my app, checking the VersionCode number against Build.CPU_ABI, then displaying an error message in case of mismatch, asking the user to re-install from Google Play (or my own website, where I post a "fat" APK) in such case.

格雷格

这篇关于Android - 为不同的处理器架构构建单独的 APK的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆