Android Studio — — JNI初体验(三)

3 篇文章 0 订阅
1 篇文章 0 订阅

NDK PREBUILT 共享库

Android NDK r5开始支持预编译共享库,共享库分为静态.a与动态.so,相对与将源码提供给使用者这种方式更为便捷,而第三方使用者直接将so库放到项目对应目录下并加载使用即可。

NDK 编译so库(内部依赖共享库)

本章节主要讲解下自己如何搭建并编译动态库的方式(内部依赖第三方动态共享库),说白了就是现在要用ndk自己编译so库,内部方法依赖其他库(预编译库),如果预编译库没有在mk文件中声明独立模块的话将编译不通过,因为内部方法找不到,也不知从哪儿找。

针对这一需求,我做了较详细的讲解,根据步骤操作就可以实现。

一:前提

Android Studio中NDK配置成功

NDK环境变量配置成功

JNI相关目录搭建成功 (可参照 Android Studio——JNI 初体验(二)

确保预编译共享库存在(需要保证共享库ABI的兼容性)

二:操作步骤

  • jni目录下新建预编译so库所对应的cpu abi类型文件夹,并将对应abi类型的so文件放到目录下,如下图红线部分,将预编译库放到目录下(因为这里的预编译库支持armeabi-v7a、x86类型,这里的预编译库为a.so 、b.so)

  • 更改Android.mk文件为(引用2个动态库):

    LOCAL_PATH:= $(call my-dir)  //当前jni目录,位与第一行
    include $(CLEAR_VARS)  //清除全局变量,防止下次使用出错
    LOCAL_MODULE := a   //第三方动态库名称
    LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/liba.so  //$(TARGET_ARCH_ABI)根据abi类型查找对应的so库
    include $(PREBUILT_SHARED_LIBRARY)    //预构建动态库

    include $(CLEAR_VARS)
    LOCAL_MODULE := b  
    LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libb.so
    include $(PREBUILT_SHARED_LIBRARY)

   include $(CLEAR_VARS)
   LOCAL_MODULE := plugin
   LOCAL_SRC_FILES := main.c otp_gen.c sotp_crypto.c    //编译so库的源文件,多个文件加空格分割
   LOCAL_SHARED_LIBRARIES := liba libcrypto  //动态库间也用空格分割
   LOCAL_LDLIBS := -llog -lz -lm 
   include $(BUILD_SHARED_LIBRARY)     //  动态库

  • Application.mk 修改ABI类型

   因为预编译库只支持上述的两种类型,所以自己编译时就将ABI类型改为armeabi与x86

          

APP_MODULES:需要编译的模块名称,可以是多个,用空格分割,模块名称由Android.mk文件中的LOCAL_MODULE指出,现在特指所有的LOCAL,与默认效果一样。

  • 更改完成后运行ndk-build生成库文件

 

三:错误集结

操作过程中遇到的问题做了下总结,如果有其他错误可以相互讨论

1:LOCAL_SRC_FILES points to a missing file 对应ABI目录下没有找到so库,根据提示信息确认每个支持的ABI目录下预编译库

1:Error:ABIs [armeabi] are not supported for platform. Supported ABIs are [arm64-v8a, armeabi-v7a, x86, x86_64].

错误原因:build.gradle配置了ndk不支持的cpu架构类型

ndk{
    abiFilters 'x86',"armeabi"
}

改为支持的cpu架构重新编译即可:

ndk{
    abiFilters 'x86',"armeabi-v7a"
}

2:使用ndk-build命令报:Android NDK: Could not find application project directory !
      Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.

  • 配置了ndk环境变量时,此命令并非在程序jni目录下编译所导致找不到项目路径
  • 未配置环境变量时,直接在ndk所在的目录下(c:\ndk-r13\ndk-bundle)运行此命令导致,需更改命令为:

     ndk-build  --directory=E:\BaiduNetdiskDownload\s\SOTPV2Test_chengdu\app\src\main\jni即可编译

    注意标注的红色部分

3:Android NDK: The armeabi ABI is no longer supported. Use armeabi-v7a.  不再支持armeabi ABI。使用ARMEBAI V7A
     Android NDK: NDK Application 'local' targets unknown ABI(s): armeabi  NDK应用程序“本地”目标未知ABI:Armeabi
     Android NDK: Please fix the APP_ABI definition in xx/jni/Application.mk  更改Application.mk 文件中的abi类型

原来Application.mk:

APP_ABI := x86 armeabi

APP_MODULES := local

根据翻译情况得知,需要更改.mk文件中的abi类型

更改Application.mk:

APP_ABI := x86 armeabi-v7a
APP_MODULES := local

5:xx/obj/local/arm64-v8a/libxx.so: error adding symbols: File in wrong format     添加符号时出错:文件格式错误

clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)  clang++.exe:错误:链接器命令失败,退出代码为1(使用-v查看调用)

原Application.mk:

APP_ABI := x86 armeabi-v7a arm64-v8a

导致失败的原因为libxx.so不支持arm64-v8a类型的

6:Unable to recognise the format of the input file xx/main/libs/armeabi-v7a/libxx.so 无法识别输入文件的格式

make: *** xx/main/libs/armeabi-v7a/libxx.so] Error 1  
make: *** Deleting file `xx/main/libs/armeabi-v7a/libxx.so'    正在删除文件
make: Leaving directory `xx/main/jni'   

因为jni/armeabi-v7a/libxx.so库是从jni/x86/中考出来的,cpu abi类型不对,所以自动将编译好的armeabi-v7a/libxx.so错误文件删除掉,根据abi类型编译各自的库,不能混着用

四:ndk版本对比

根据版本不同编译不同类型的so文件,platforms 与prebuilt下可以查看支持的ABI类型,这只是个人理解,误喷但可以纠正,期待~~

    
 

附:splits配置abi类型

android {
    ... // 其它配置
    splits {
        abi {
            reset()
            enable true // 设为true,才能在打包时根据架构生成不同的apk文件
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86" // 设置所有要支持的abi类型
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值