如何在64位安卓系统中使用32位SO库

背景知识:

对于64位系统的编译规则,可参考:http://source.android.com/source/64-bit-builds.html


关键点:

  • JAVA编译不分32bit和64bit(APK,JAR)
  • 可执行文件,默认编译64位
  • 动态库和静态库,默认同时编译32bit和64bit版本
  • 通过LOCAL_MULTILIB可以指定特定模块编译32bit或64bit或都编译
  • JAVA加载JNI库(so文件)的规则:
    如果APP需要加载的所有so都是32bit,则使用32bit方式加载so库;如果APP需要加载的so库中只要有一个so是64bit的,则必须以64bit方式加载so库;不能同时加载32bit和64bit的so库。

实际工程中,我们通常会遇到下面这样的场景:
A. APK有源码,SO库有源码 - 应用及so库我们都能自己编译出来
B. APK有源码,SO库没有源码 - 我们开发的应用使用了第三方的so库,如ScanService
C. APK和SO库都没有源码 - 预置第三方的应用(应用中包括so库)

对于场景A:

只要我们编译默认对应的APP和SO库(32bit+64bit)即可。
此种场景最为普通,本文不做详细讲解。

对于场景B:

如果APK需要加载的库里面有64bit的,则需要全部的库都使用64bit。
如果APK调用的第三方so库中有32bit的,则:要么让第三方提供64bit版本的so库,要么强制使所以的so库都使用32bit版本

对于场景C:

使用特定的预置规则即可。


场景A范例:

  • APK的编译规则不需要设置LOCAL_MULTILIB
  • SO库的编译规则也不需要设置LOCAL_MULTILIB
    所以,SO库就会同时编译出32bit和64bit版本,APK按照64bit方式调用so库

场景B范例:

  • APK的编译规则需要设置LOCAL_MULTILIB
  • SO库的编译规则需要指定64bit或32bit(本地编译或预置的都需要)
  • 需要显示声明APK的JNI库
    如:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_JAVA_LIBRARIES := odm conscrypt sp
LOCAL_PACKAGE_NAME := PosService

# to support on 64-bit system
LOCAL_JNI_SHARED_LIBRARIES := \
                          libmiscjni \
                          libttyjni \
                          libIAL \
                          libSDL \
                          libbarcodereader \
                          libHsmKil \
                          libHHPScanInterface \
                          libHSMDecoderAPI
LOCAL_MULTILIB := 32

include $(BUILD_PACKAGE)

其中某个本地编译so的规则:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    com_odm_tty.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libttyjni
LOCAL_MULTILIB := 32
include $(BUILD_SHARED_LIBRARY)

某个第三方so的规则:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE := libHHPScanInterface
LOCAL_SRC_FILES := $(LOCAL_MODULE).so
LOCAL_MODULE_PATH := $(TARGET_OUT)/lib
LOCAL_MULTILIB := 32
include $(BUILD_PREBUILT)

场景C范例:

  • APK使用典型的预置应用规则
  • SO库不需要写预置规则
  • 需要显示声明APK调用的SO库
    如:
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := BaiduIME
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := baidu_input_for_xiaomiV5.apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MULTILIB := 32
LOCAL_PREBUILT_JNI_LIBS := \
    @lib/armeabi/libBDVoiceRecognitionClient_V1.so \
    @lib/armeabi/libchiperencoder_v1_2_1.so \
    @lib/armeabi/librabjni-1.so \
    @lib/armeabi/libshare_v2.so
include $(BUILD_PREBUILT)

粗体部分是需要特别注意的地方。

你可能感兴趣的:(Android)