AS如何引入第三方so

AS如何引入第三方so

背景

Android Studio 引入第三方so以及头文件。

情况一:
仅需直接引入SO,并直接调用其暴露的JNI方法

情况二:
无法调用JNI方法,需要引入头文件,在C++层调用其导出方法

情况一解决方案:
  • 在src/main/ 目录下新建目录 jniLibs
  • 在jniLibs目录下新建目录 armeabi-v7a
  • 将so文件以及Needed Library文件copy到armeabi-v7a目录下
  • 在build.gradle中,添加以下代码:
android {
...
sourceSets {
       main {
           jniLibs.srcDirs = ['src/main/jniLibs']
       }
   }
}
  • sync now

备注:要注意包名需要相匹配,同时假设无法运行,可能原因是so文件有做签名校验

情况二解决方案

修改CMakeLists.txt,如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
        uUtils

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        ${CMAKE_SOURCE_DIR}/src/main/cpp/uDemo.cpp )


# 添加第三方so
add_library(u_jni SHARED IMPORTED)

# 添加第三方so所在位置
set_target_properties(u_jni PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libu_jni.so)

# 添加头文件
include_directories(uUtils
        PRIVATE
        ${CMAKE_SOURCE_DIR}/src/main/cpp/include)

set_property(TARGET u_jni PROPERTY IMPORTED_NO_SONAME 1)

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log )

# 链接so
target_link_libraries( # Specifies the target library.
        uUtils

        u_jni
        android
        ${log-lib} )

修改build.gradle

defaultConfig {
	...
	externalNativeBuild {
        cmake {
            cppFlags "-frtti -fexceptions"
        }
    }
    ndk {
        abiFilters "armeabi-v7a"
    }
}
externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
}
sourceSets {
    main {
        jniLibs.srcDirs += ['libs']
    }
}

踩坑记录

引入其中某一个SO文件时,其LD_LIBRARY_PATH即Need library一直为相对路径

可以看到这两个 so 文件有个差别就是 libloki.so 缺少了 SONAME。

CMake 在用 add_library(XXX SHARED IMPORTED) 并通过 IMPORTED_LOCATION 指定 lib full path 导入 lib 时会看这个 lib 有没有 SONAME。如果有的话就把 lib full path 截断并通过 -L/path/to/libXXX -lXXX来链接,如果没有的话就会用全路径 -l/path/to/libXXX.so 来链接。这会导致在链接生成的文件里面 NEEDED 字段一个是 lib name 一个是 lib full path。

解决方案:

set_property(TARGET loki PROPERTY IMPORTED_NO_SONAME 1)

参考

用 CMake 的一点经验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值