Android库中缺少x86架构的.so文件?(Vuforia)

3
我希望在Android项目中集成Vuforia增强现实库(jni)。AR不是应用程序的核心,更像是一个附加功能。但是Vuforia库不支持x86体系结构,这意味着x86 Android手机将无法下载该应用程序。
有没有一种方法可以授权x86手机下载应用程序,并且只需不让它们玩转应用程序的AR部分?这意味着一种编译x86架构的方法,缺少一个库,并且还要检测应用程序运行的架构?
我知道并不是有很多x86的Android手机,最终,我可能被迫等待Vuforia发布其.so的x86版本,但我希望知道是否有一种方法可以实现我所描述的内容。

1
如果您能够使用NDK,只需构建一个模拟Vuforia接口的库,并将该x86构建添加到您的项目中即可。 - auselen
这是一个好主意,看起来API中有大量的.h文件和方法列表,似乎需要做很多工作。我想我得为此创建一个副项目。 - jptsetung
只需要添加一个函数即可,在x86上返回“no”,在ARM上返回“yes”,前提是当该函数返回“no”时,不要调用Vuforia。我的理解是,尝试调用这些函数将会导致运行时异常,但我并不完全确定(特别是在不同的Android版本之间)。 - tc.
@tc,谢谢,看看我的答案,我解决了这个问题。 - jptsetung
@tc。这是关于应用在市场上可见性的问题,正如您所链接的帖子所描述的那样,以及可能解决方案的方式。 - auselen
显示剩余2条评论
2个回答

1
你可以使用工具(比如cmock)从头文件创建存根,然后使用NDKx86构建并在应用程序中使用生成的so(共享对象)来模拟vuforia
在这种情况下,您还应该在代码中很好地处理不同的体系结构,这可能意味着读取诸如Build.CPU_ABI之类的值。
我建议您将此类项目放在github下,以便其他人也可以从中受益。我不是许可证方面的专家,但使用头文件应该是合法的。

@jptsetung 你知道有一个感谢的按钮吗 ;) - auselen

1

实际上,我很容易地解决了这个问题。感谢 @auselen 的帮助。

您有一个常规的 Android.mk,在 x86 架构上失败,因为您正在使用的库(libExternalLibrary.so)仅针对 arm 架构提供。您想要基于此库构建一个 .so(libMyLibraryBasedOnExternalLibrary.so)。

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

(+1) 你不能利用工具从可用的头文件创建模拟实现吗? - auselen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接