[✔️] android JNI学习

简介: [✔️] android JNI学习

举个栗子


github.com/tidys/learn…


  • build.gradle设置


android {
    defaultConfig {
        ndk {
            moduleName "native-lib" // 指定库的名字
            abiFilters "x86" // 如果不指定平台,AndroidStudio默认会生成所有平台的so
        }
    }
    externalNativeBuild {
        cmake {
            version "3.10.2"
            path "CMakeLists.txt"
        }
    }
}


  • CMakeLists.txt


cmake_minimum_required(VERSION 3.4.1)
add_library(native-lib SHARED src/main/cpp/native-lib.cpp )
find_library(log-lib log )
target_link_libraries(native-lib ${log-lib} )


  • src/main/cpp/native-lib.cpp


可以使用java-h生成对应的头文件,


#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_example_learnndk_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++!";
    return env->NewStringUTF(hello.c_str());
}


将APK解压后发现在lib目录的确存在我们编写的c++库


image.png


编译自己的c++库


编译使用jni有两种构建方式,:


  • CMake:Android studio新的构建方式,Project Path需要选择CMakeList.txt文件路径,jni会按照这个脚本来进行编译,具体脚本的编写看下面。


  • ndk-build:老eclipse的构建方式,也就是Android.mk、Appli.mk的形式。


ndk-build


Android.mk


LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native-lib
LOCAL_SRC_FILES := ../src/main/cpp/native-lib.cpp
# include $(BUILD_SHARED_LIBRARY) # 编译为动态库
# include $(BUILD_STATIC_LIBRARY) # 编译为静态库


  • LOCAL_MODULE :lib的名字


  • LOCAL_SRC_FILES:编译的源代码


  • LOCAL_C_INCLUDES: 头文件目录


  • LOCAL_SHARED_LIBRARIES: 当前模块依赖的动态库模块


  • LOCAL_STATIC_LIBRARIES: 当前模块依赖的静态库模块


  • PREBUILT_STATIC_LIBRARY:用来指定一个预先已经编译好的静态库


  • PREBUILT_SHARED_LIBRARY:用来指定一个预先已经编译好的动态库,与BUILD_SAHRED_LIBRARYBUILD_STATIC_LIBRARY不同,该模块对应的LOCAL_SRC_FILES不能是源文件,而只能是一个已经编译好的的动态库的路径,如foo/libfoo.so


  • LOCAL_LDFLAGS := 静态动态都可以


Application.mk


项目级别的设置




APP_STL := c++_shared # 会多出来一个libc++_shared.so
APP_STL := c++_static 



APP_CPPFLAGS := -std=c++11 # 支持c++11


常见错误


ld: error: undefined symbol: std::__ndk1::basic_string<char,


APP_STLApplication.mk中定义,不能在Android.mk中定义,没有用


APP_STL := c++_shared # 动态库使用
APP_STL := c++_static # 静态库使用
APP_STL := gnustl_static # 低版本 静态库使用


项目之间相互引用


  • settings.gradle


include ':Project1' 
project(':Project1').projectDir = new File(settingsDir, '../Project1')


  • build.gradle


dependencies {  
  compile project(":Project1")  
}


import-module


导入外部模块的.mk文件 ,和 include基本一样。


  • include导入的是由我们自己写的.mk,路径是.mk文件的绝对路径


  • import-module导入的是外部库、外部模块提供的.mk,路径是相对于
  • NDK_MODULE_PATH中的路径列表的相对路径。


示例:


$(call import-module,相对路径)


NDK_MODULE_PATH


设置NDK_MODULEPATH的几种方法:


  1. 系统环境变量


  1. 直接将NDK_MODULE_PATH=路径1:路径2 加到 ndk-build命令的参数后面,ndk-build的参数最终会直接传给make


  1. 在import之前加入$(call import-add-path,$(LOCAL_PATH)),cocos2dx选择的是这种方式


Gradle Wrapper


Gradle Wrapper称为Gradle包装器,是对Gradle的一层包装。为什么需要Gradle Wrapper呢?比如在一个开发团队中,如果每进来一个成员,都需要在计算机中安装Gradle,这个时候运行Gradle的环境和版本就会对构建结果带来不确定性。针对这个问题,Gradle提供了一个解决方案,那就是Gradle Wrapper,它是一个脚本,可以在计算机没有安装Gradle的情况下运行Gradle构建,并且能够指定Gradle的版本,开发人员可以快速启动并运行Gradle项目,而不必手动安装,这样就标准化了项目,从而提高了开发效率。AS在新建项目时会自带Gradle Wrapper,这也是我们很少去单独去下载安装Gradle的原因。


执行:


gradle wrapper


这时会在项目根目录中生成如下文件:


├── gradle 
│ └── wrapper 
│ ├── gradle-wrapper.jar 
│ └── gradle-wrapper.properties 
├── gradlew 
└── gradlew.bat


  • gradle-wrapper.jar :包含Gradle运行时的逻辑代码。


  • gradle-wrapper.properties :负责配置包装器运行时行为的属性文件,用来配置使用哪个版本的Gradle等属性。


  • gradlew:Linux平台下,用于执行Gralde命令的包装器脚本。


  • gradlew.bat:Windows平台下,用于执行Gralde命令的包装器脚本。


目录
相关文章
|
5月前
|
Android开发
Android JNI与CAN通信遇到的问题总结
Android JNI与CAN通信遇到的问题总结
180 1
|
5月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
145 0
|
5月前
|
Android开发
Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
769 1
|
2月前
|
Java Android开发 C++
Android Studio JNI 使用模板:c/cpp源文件的集成编译,快速上手
本文提供了一个Android Studio中JNI使用的模板,包括创建C/C++源文件、编辑CMakeLists.txt、编写JNI接口代码、配置build.gradle以及编译生成.so库的详细步骤,以帮助开发者快速上手Android平台的JNI开发和编译过程。
170 1
|
28天前
|
Java Maven 开发工具
第一个安卓项目 | 中国象棋demo学习
本文是作者关于其第一个安卓项目——中国象棋demo的学习记录,展示了demo的运行结果、爬坑记录以及参考资料,包括解决Android Studio和maven相关问题的方法。
第一个安卓项目 | 中国象棋demo学习
|
10天前
|
Web App开发 编解码 视频直播
视频直播技术干货(十二):从入门到放弃,快速学习Android端直播技术
本文详细介绍了Android端直播技术的全貌,涵盖了从实时音视频采集、编码、传输到解码与播放的各个环节。文章还探讨了直播中音视频同步、编解码器选择、传输协议以及直播延迟优化等关键问题。希望本文能为你提供有关Andriod端直播技术的深入理解和实践指导。
15 0
|
1月前
|
Android开发
Android学习 —— 测试init.rc中的条件触发的处理顺序
Android学习 —— 测试init.rc中的条件触发的处理顺序
|
5月前
|
监控 Unix 应用服务中间件
Android-音视频学习系列-(八)基于-Nginx-搭建(rtmp、http)直播服务器
Android-音视频学习系列-(八)基于-Nginx-搭建(rtmp、http)直播服务器
|
2月前
|
搜索推荐 Android开发
学习AOSP安卓系统源代码,需要什么样的电脑?不同配置的电脑,其编译时间有多大差距?
本文分享了不同价位电脑配置对于编译AOSP安卓系统源代码的影响,提供了从6000元到更高价位的电脑配置实例,并比较了它们的编译时间,以供学习AOSP源代码时电脑配置选择的参考。
176 0
学习AOSP安卓系统源代码,需要什么样的电脑?不同配置的电脑,其编译时间有多大差距?
|
5月前
|
存储 定位技术 开发工具
Android 开发前的设计,Android之内存泄漏调试学习与总结
Android 开发前的设计,Android之内存泄漏调试学习与总结