0

我正在尝试通过使用一些本机库来开发一个 android 应用程序。但是,系统共享库android 4.0android 4.1.2不同。为了保证兼容性,我从平台 4.0 获取 libskia.so 文件,并将其导入到我的项目中。我希望像使用第 3 方共享库一样加载这个共享库。不幸的是,在运行时android 4.1.2,我的应用程序似乎仍然调用系统skia 库。我对此一无所知,以下是我的Android.mk文件

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := sample
LOCAL_SRC_FILES := sample-jni.cpp

LOCAL_CFLAGS    := -I /home/WORKING_DIRECTORY/external/skia/include \
-I /home/WORKING_DIRECTORY/external/skia/include/core \
-I /home/WORKING_DIRECTORY/frameworks/base/core/jni/android/graphics  \
-I /home/WORKING_DIRECTORY/frameworks/base/include \
-I /home/WORKING_DIRECTORY/frameworks/base/native/include/android \
-I /home/WORKING_DIRECTORY/system/core/include \
-I /home/WORKING_DIRECTORY/external/skia/include/xml \
-I /home/WORKING_DIRECTORY/external/skia/include/images \
-I /home/WORKING_DIRECTORY/external/skia/include/views \

 LOCAL_SHARED_LIBRARIES :=skia jnigraphics
 include $(BUILD_SHARED_LIBRARY)
 include $(LOCAL_PATH)/prebuilt/Android.mk

和预建的makefile

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := skia
LOCAL_SRC_FILES := libskia.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := jnigraphics
LOCAL_SRC_FILES := libjnigraphics.so
include $(PREBUILT_SHARED_LIBRARY)

有任何想法吗?或者,是否有任何其他方法来确保兼容性?

4

2 回答 2

0

您可以使用带有参数 RTLD_DEEPBIND 的本机代码中的 dlopen 来使用不同版本的 libskia。这将覆盖全局符号表。

于 2014-08-29T18:39:11.160 回答
0

我希望你明白,除了稳定的 API之外,不建议对系统库有任何依赖。但 Android 的开放性允许(无论是在技术上还是在许可方面)引入这种依赖关系。从本质上讲,这意味着在非特许水域航行,并且不仅准备在平台的下一版本中进行 API 更改,而且还准备在同一平台级别的供应商提供(即非 AOSP)设置中进行 API 更改。

从理论上讲,您可以将系统库的变体副本放入应用程序的libs/armeabi-v7a文件夹中,并使用System.load(fullPath)而不是loadLibrary()加载它。

但在实践中,我相信system/lib/libskia.so将在您有机会执行代码之前加载到您的进程中,并且您不能在同一进程中加载​​同一个库的两个版本。此外,旧版本的libskia很可能无法在系统上加载,因为它依赖于其他系统库。

确保前向(和供应商)兼容性的最安全方法是对未记录的系统功能使用动态链接,并在此过程中执行仔细的错误检查。

但在很多情况下,系统无文档的 API 实际上是相当稳定的,而且 Google 的 Android 团队中的好人不会经常进行重大更改。因此,如果您链​​接到 4.0 版本的skia ,您的代码很可能只会在 4.1.2 及更高版本上运行......

更新:在你的特殊情况下,当一个额外的字段fTextLocale被添加到一个旧的类中时,你应该首先祝福那些没有在类声明中间插入这个字段的开发人员。因为现在您有了一个合理的策略:使用 4.1.2 标头(带有额外字段),链接到 4.0 库(不会将访问器方法引入新字段),并且您的代码有望正常工作。

于 2013-02-03T09:27:14.853 回答