2012-06-01 46 views
9

Google Play应用商店会自动将您的应用过滤为兼容CPU架构的设备。例如。如果您有一个仅针对ARMv5编译的库,则您的应用只会显示具有ARMv5或ARMv7处理器的设备。Android NDK和Google Play过滤

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

当我上传.apk文件,Android开发者控制台说: “该apk请求将被用于谷歌Play筛选 armeabi 1个的原生平台”

我需要编译的x86虚拟图书馆和MIPS?然后在我的Java代码中,检查处理器体系结构以确定我是否可以真正使用该库?应该有更好的解决方案。

据我所知,目前还没有在清单有关CPU架构,我无法找到在开发者控制台的方式来关闭这个滤波器。

希望有人知道比我做的更多的Google Play过滤和NDK知道答案。

+0

可能解决/嘲笑的想法:http://stackoverflow.com/questions/15146174/android-library-so-with-x-86-architecture-missing-vuforia – auselen

回答

11

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

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

从理论上讲,所有平台的建设都可以针对所有设备,但实际上有一些设备如Google Tv不报告ABI,这意味着只有没有本地代码的apks才会出现在Play中存储在这些设备上。您可以使用多个apks,但是,1不支持本机代码,1支持所有支持本机代码的平台。

您可以了解多个APK支持位置:http://developer.android.com/guide/market/publishing/multiple-apks.html

+0

相反(我现在要做的)呢?我有一个使用v5(或某些)库的v7应用程序。这意味着即使主应用程序仅适用于v7,我也有两种体系结构的库。目前我们刚刚将非v7文件移动到v7文件夹中,它似乎可行,但它确实很丑陋,也是错误的。由于需要两个本地库,所以我们不能将它分割成多个apks。 – alaeus

+0

@alaeus这应该是一个单独的问题。这也很好--Android保持了ABI的向后兼容性,所以ARMv5代码在ARMv6/7设备上运行得很好(特别是它们都使用“软浮点”ABI,这会对性能造成严重损失,我们必须忍受)。 –

6

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

让我发表我自己的解决方案,这几乎是我在这里张贴相同:Android library .so with x86 architecture missing? (Vuforia)

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

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

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) 
    // ... 
} 
+0

当我尝试类似步骤时,出现以下错误:/android/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/../lib/gcc/arm-linux-androideabi/ 4.6.x-google /../../../../ arm-linux-androideabi/bin/ld:error:找不到-lExternalLibrary.so collect2:ld返回1退出状态 –

+0

这是一个编译错误哪个架构?你能在日志中看到Dummy0.cpp的汇编吗? – jptsetung

+0

我正在为Arm架构构建,但是第一个库ExternalLibrary.so被生成了。我不知道为什么它会在构建arm架构时到达其他部分。我应该使用Ndk方法而不是这个吗? –