11

Google Play 应用商店会自动将您的应用程序过滤到具有兼容 CPU 架构的设备上。例如,如果您有一个仅为 ARMv5 编译的库,那么您的应用程序将只显示在具有 ARMv5 或 ARMv7 处理器的设备上。

如果我有 Java 替代方案,并且希望我的应用程序也可以由非 ARM 设备下载怎么办?例如,我在尝试加载外部库时捕获了一个异常,并在 Dex 字节码 (Java) 中实现了一个可行的替代方案。

当我上传 .apk 时,Android 开发者控制台显示:“此 apk 请求 1 个本机平台,将用于 Google Play 过滤。armeabi”

我需要为 x86 和 MIPS 编译虚拟库吗?然后在我的 Java 代码中,检查处理器架构以了解我是否可以实际使用该库?应该有更好的解决方案。

据我所知,Manifest 中没有关于 CPU 架构的任何内容,而且我在开发者控制台中找不到关闭此过滤器的方法。

希望比我更了解 Google Play 过滤和 NDK 的人知道答案。

4

2 回答 2

11

虽然对 loadLibrary 故障的捕获将适用于任何设备(至少我尝试过的所有设备,包括 GTV),但如果该平台的 ABI 在 apk 中不存在,Play Store 将不会显示在设备上。

来自文档(http://developer.android.com/guide/appendix/market-filters.html):包含针对特定平台(例如 ARM EABI v7 或 x86)的本机库的应用程序仅在支持该平台的设备。

理论上,为所有平台构建将能够针对所有设备,但实际上有一些设备(如 Google Tv)报告没有 ABI,这意味着只有没有本机代码的 apk 才会出现在这些设备上的 Play 商店中. 但是,您可以使用多个 apk,其中 1 个没有本机代码,1 个与支持您的本机代码的所有平台一起使用。

您可以在此处阅读有关多 apk 支持的信息:http: //developer.android.com/guide/market/publishing/multiple-apks.html

于 2012-06-03T03:07:32.403 回答
6

这里有同样问题的非常完整的答案:http: //grokbase.com/t/gg/android-ndk/125v31e6wy/play-store-market-filtering-of-ndk-libs

让我发布我自己的解决方案,这与我在这里发布的几乎相同:Android library .so with x86 architecture missing? (武佛利亚)

因此,您有一个无法在 x86 架构上编译的常规 Android.mk,因为您使用的库 (libExternalLibrary.so) 仅提供给 arm 架构。你想基于这个库构建一个 .so (libMyLibraryBasedOnExternalLibrary.so),当然如果没有这个库,它永远不会在 x86 上编译。

这个想法是直接在 Android.mk 中使用条件编译指令为 x86 生成 Dummy 库。

1) 创建 2 个虚拟 .cpp 文件 Dummy0.cpp 和 Dummy1.cpp 示例 Dummy0.cpp 如下所示:

#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <string>

#ifdef __cplusplus
extern "C"
{
#endif

int dummy0                        =  0;

#ifdef __cplusplus
}
#endif

然后,编辑构建你的库的 Android.mk 并像这样修改它:

LOCAL_PATH := $(call my-dir)

ifeq ($(TARGET_ARCH_ABI), armeabi)


# In this condtion block, we're compiling for arm architecture, and the libExternalLibrary.so is avaialble
# Put every thing the original Android.mk was doing here, importing the prebuilt library, compiling the shared library, etc...
# ...
# ...

else

# In this condtion block, we're not compiling for arm architecture, and the libExternalLibrary.so is not availalble.
# So we create a dummy library instead.

include $(CLEAR_VARS)
# when LOCAL_MODULE equals to ExternalLibrary, this will create a libExternalLibrary.so, which is exactly what we want to do.
LOCAL_MODULE := ExternalLibrary
LOCAL_SRC_FILES := Dummy0.cpp
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
# This will create a libMyLibraryBasedOnExternalLibrary.so
LOCAL_MODULE := MyLibraryBasedOnExternalLibrary
# Don't forget to tell this library is based on ExternalLibrary, otherwise libExternalLibrary.so will not be copied in the libs/x86 directory
LOCAL_SHARED_LIBRARIES := ExternalLibrary
LOCAL_SRC_FILES := Dummy1.cpp
include $(BUILD_SHARED_LIBRARY)

endif

当然,请确保在您的代码中,当您的应用在仅 x86 的设备上运行时,您永远不会调用该库:

if ((android.os.Build.CPU_ABI.equalsIgnoreCase("armeabi")) || (android.os.Build.CPU_ABI2.equalsIgnoreCase("armeabi"))) {
    // Good I can launch
    // Note that CPU_ABI2 is api level 8 (v2.2)
    // ...
}
于 2013-03-04T06:46:49.773 回答