简体   繁体   English

Android APK生成未获取.so文件-为什么?

[英]Android APK generation is not picking up .so file — why?

I have an Android build environment on my Mac. 我的Mac上有一个Android构建环境。 When I run ant debug , it cleanly packages up libandroidnative.so inside the APK file for deployment. 当我运行ant debug ,它将libandroidnative.so干净地打包在APK文件中以进行部署。 This works as expected. 这按预期工作。

I am migrating my build setup over to a Windows PC. 我正在将构建设置迁移到Windows PC。 When I run ant debug , it successfully completes without packaging up `libandroidnative.so' into the APK file. 当我运行ant debug ,它成功完成,而没有将`libandroidnative.so'打包到APK文件中。

The codebases are exactly the same -- this is a pull from the same repo. 代码库完全相同-这是来自同一存储库的信息。 The versions of the NDK (r8) and SDK (2013-05-22) are exactly the same. NDK(r8)和SDK(2013-05-22)的版本完全相同。

Here is a (working) output on my Mac: 这是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

Here is the non-working output on my PC: 这是我的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

Note that the same thing happens from an Eclipse build. 请注意,Eclipse构建也会发生相同的情况。

Here is my Ant build file (sans comments): 这是我的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>

I got it. 我知道了。 TLDR; TLDR; eclipse deletes the old .so file before generating the new one, regardless of whether running ndk-build generates a new one . eclipse会在生成新文件之前删除旧的.so文件, 无论运行ndk-build是否生成新文件 Make sure that an ndk-build command creates a new one. 确保ndk-build命令创建一个新命令。

In my case, I was only building if an environment variable was set to a certain value. 就我而言,我只是在将环境变量设置为某个值的情况下进行构建。 I had a logic branch in my Android.mk that silently exited if the environment variable was a mismatch. 我的Android.mk中有一个逻辑分支,如果环境变量不匹配,则会自动退出。

On Linux/Mac, you can type set SOME_VAR="foo" . 在Linux / Mac上,您可以键入set SOME_VAR="foo" In a batch file on Windows, typing set SOME_VAR="foo" includes the quotes in the environment variable name. 在Windows的批处理文件中,键入set SOME_VAR="foo"在环境变量名称中包含引号。

Awful and totally my fault. 糟糕透顶,完全是我的错。 I am keeping the question up because the general wisdom at the start of this question may be relevant. 我会继续提出这个问题,因为这个问题开始时的普遍智慧可能是相关的。

Also worth understanding: you can type aapt list bin\\somepackage.apk to generate the listings I used in the original posting. 还值得理解:您可以键入aapt list bin\\somepackage.apk生成我在原始帖子中使用的列表。

According to http://docs.xamarin.com/guides/android/advanced_topics/cpu_architecture , the native libraries behaved differently for different android versions. 根据http://docs.xamarin.com/guides/android/advanced_topics/cpu_architecture ,对于不同的android版本,本机库的行为有所不同。

Android prior to 4.0 Ice Cream Sandwich will only extract native libraries from a single ABI within the .apk 低于4.0 Ice Cream Sandwich的Android将仅从.apk中的单个ABI中提取本地库

Consequently, when targeting Android versions prior to 4.0, it is necessary to provide all native libraries for each ABI that the application will support. 因此,以4.0之前的Android版本为目标时,有必要为应用程序将支持的每个ABI提供所有本机库。

and further on, it mentions that 并进一步提到

Android 4.0 Ice Cream Sandwich changes the extraction logic. Android 4.0冰淇淋三明治会更改提取逻辑。 It will enumerate all native libraries, see if the file's basename has already been extracted, and if both of the following conditions are met, then the library will be extracted 它将枚举所有本机库,查看是否已提取文件的基本名称,并且如果同时满足以下两个条件,则将提取该库

It hasn't already been extracted. 尚未提取。 The native library's ABI matches the target's primary or secondary ABI. 本地库的ABI与目标的主要或辅助ABI相匹配。

Unfortunately, this behavior is order dependent. 不幸的是,这种行为是依赖顺序的。

The native libraries are processed “in order” (as listed by, for example, unzip), and the first match is extracted. 本地库是“按顺序”处理的(例如,通过解压缩列出),并提取第一个匹配项。 Since the .apk contains armeabi and armeabi-v7a versions of libtwo.so, and the armeabi is listed first, it's the armeabi version that is extracted, not the armeabi-v7a version: 由于.apk包含libtwo.so的armeabi和armeabi-v7a版本,并且首先列出了armeabi,因此提取的是armeabi版本,而不是armeabi-v7a版本:

> It is recommended, if the app will run on Android prior to 4.0.4, that the app contain onlyarmeabi-v7a, not armeabi. >建议,如果该应用程序将在4.0.4之前的Android上运行,则该应用程序仅包含armeabi-v7a,而不包含armeabi。 Including x86 or any other ABI won't cause problems; 包括x86或任何其他ABI都不会引起问题; it's only the inclusion of both armeabi and armeabi-v7a is an issue. 仅包含armeabi和armeabi-v7a是一个问题。

and for post 4.0.4 对于4.0.4

Android 4.0.4 changes the extraction logic: it will enumerate all native libraries, read the file's basename, then extract the primary ABI version (if present), or the secondary ABI (if present). Android 4.0.4更改了提取逻辑:它将枚举所有本机库,读取文件的基本名称,然后提取主要ABI版本(如果存在)或次要ABI版本(如果存在)。 This allows “merging” behavior 这允许“合并”行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM