0

我的 Mac 上有一个 Android 构建环境。当我运行时ant debug,它会干净地打包libandroidnative.so在 APK 文件中以进行部署。这按预期工作。

我正在将构建设置迁移到 Windows PC。当我运行时ant debug,它成功完成,没有将 `libandroidnative.so' 打包到 APK 文件中。

代码库完全相同——这是从同一个 repo 中提取的。NDK (r8) 和 SDK (2013-05-22) 的版本完全相同。

这是我的 Mac 上的(工作)输出:

res/layout/main.xml
AndroidManifest.xml
resources.arsc
res/drawable-hdpi/ic_launcher.png
res/drawable-ldpi/ic_launcher.png
res/drawable-mdpi/ic_launcher.png
res/drawable-xhdpi/ic_launcher.png
classes.dex
lib/armeabi/gdbserver
lib/armeabi/libandroidnative.so  <--- success!
lib/x86/gdbserver
lib/x86/libandroidnative.so
META-INF/MANIFEST.MF
META-INF/CERT.SF
META-INF/CERT.RSA

这是我的 PC 上的非工作输出:

res/layout/main.xml
AndroidManifest.xml
resources.arsc
res/drawable-hdpi/ic_launcher.png
res/drawable-ldpi/ic_launcher.png
res/drawable-mdpi/ic_launcher.png
res/drawable-xhdpi/ic_launcher.png
classes.dex
lib/armeabi/gdbserver
lib/armeabi-v7a/gdbserver
lib/x86/gdbserver
META-INF/MANIFEST.MF
META-INF/CERT.SF
META-INF/CERT.RSA

请注意,同样的事情发生在 Eclipse 构建中。

这是我的 Ant 构建文件(无注释):

<?xml version="1.0" encoding="UTF-8"?>
<project name="AndroidNativeLayer" default="help">

    <property file="local.properties" />

    <property file="ant.properties" />

    <property environment="env" />
    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
        <isset property="env.ANDROID_HOME" />
    </condition>
    <loadproperties srcFile="project.properties" />

    <fail
            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
            unless="sdk.dir"
    />
    <import file="custom_rules.xml" optional="true" />

    <import file="${sdk.dir}/tools/ant/build.xml" />

</project>
4

2 回答 2

1

我知道了。TLDR;eclipse 会在生成新文件之前删除旧的 .so 文件,无论运行 ndk-build 是否生成新文件。确保 ndk-build 命令创建了一个新命令。

就我而言,我只在环境变量设置为某个值时才进行构建。我的 Android.mk 中有一个逻辑分支,如果环境变量不匹配,它会静默退出。

在 Linux/Mac 上,您可以键入set SOME_VAR="foo". 在 Windows 上的批处理文件中,键入 setSOME_VAR="foo"包括环境变量名称中的引号。

糟糕透顶,完全是我的错。我一直在问这个问题,因为这个问题开始时的普遍智慧可能是相关的。

还值得理解:您可以键入aapt list bin\somepackage.apk以生成我在原始帖子中使用的列表。

于 2013-07-13T19:34:57.887 回答
0

根据http://docs.xamarin.com/guides/android/advanced_topics/cpu_architecture,本机库对于不同的 android 版本表现不同。

4.0 Ice Cream Sandwich 之前的 Android 将仅从 .apk 中的单个 ABI 提取本机库

因此,当面向 4.0 之前的 Android 版本时,有必要为应用程序将支持的每个 ABI 提供所有本机库。

此外,它还提到

Android 4.0 Ice Cream Sandwich 更改了提取逻辑。它会枚举所有的原生库,看文件的basename是否已经被提取出来,如果满足以下两个条件,那么就会提取出这个库

它还没有被提取出来。本机库的 ABI 与目标的主要或次要 ABI 匹配。

不幸的是,这种行为是依赖于顺序的。

本机库被“按顺序”处理(例如,解压缩列出的),并提取第一个匹配项。由于 .apk 包含 libtwo.so 的 armeabi 和 armeabi-v7a 版本,并且首先列出了 armeabi,因此提取的是 armeabi 版本,而不是 armeabi-v7a 版本:

> 如果应用程序将在 4.0.4 之前的 Android 上运行,建议应用程序仅包含 armeabi-v7a,而不是 armeabi。包含 x86 或任何其他 ABI 不会导致问题;只是同时包含 armeabi 和 armeabi-v7a 是一个问题。

对于 4.0.4 后

Android 4.0.4 更改了提取逻辑:它将枚举所有本机库,读取文件的基本名称,然后提取主 ABI 版本(如果存在)或辅助 ABI(如果存在)。这允许“合并”行为

于 2013-08-05T16:08:31.547 回答