NDK:NDK集成开发流程

源代码 2024-9-27 08:35:52 76 0 来自 中国
一、JNI简介

JNI = Java Native Interface,Java本地接口。
二、交织编译

在什么平台运行的软件就必要在什么平台举行编译,为什么Android可以在Windows下kaifa-并在手机的unix体系上运行呢?这是由于Java是运行在假造机上的。为什么说Java是一次编译到处实验?
交织编译:在一个平台下编译出另一个平台下可以运行的本地代码

  • cpu平台 x86 arm
  • 操纵体系平台 windows linux mac os unix
  • 差别的cpu和差别的操纵体系所支持的指令集是不一样的,以是在哪个平台上的软件必要在哪个平台上举行编译。
三、NDK简介

NDK = native develop kit,本地开发工具集。
通过NDK来实现交织编译,NDK是Google提供的。
四、NDK集成开发流程(以cmake工程为例)

1、下载NDK
解压NDK的zip包到非中文目次
2、设置情况变量
根目次中有ndk-build.cmd文件,将根目次设置情况变量path中
3、在local.properties 中设置ndk根路径
ndk.dir=C:\Users\94317\AppData\Local\Android\ndk\android-ndk-r25b
4、在gradle.properties 中设置useDeprecatedNdk 属性
android.useDeprecatedNdk = true,作用是兼容老的ndk
现在,useDeprecatedNdk 已经不支持,改为cmake大概ndk-bundle
5、界说本地接口
public class JNI {    /**     * 界说本地接口     */    public native String stringFromJNI();}6、编写C++代码
在main目次下创建一个恣意名称的文件夹,好比cpp文件夹,在cpp文件夹中创建一个cpp文件,好比:native-lib.cpp,代码如下:
#include <jni.h>#include <string>using namespace std;extern "C" JNIEXPORT jstring JNICALLJava_com_nobug_jniproject_JNI_stringFromJNI(JNIEnv* env,jobject /* this */) {    string hello = "Hello from C++";    return env->NewStringUTF(hello.c_str());}extern "C":在编译时,模式是以C++11标准编译,不支持C语言的编译,以是必要添加 extern "C",可以或许让C和C++相互调用。
jstring:表示返回值是string范例
7、cmake设置
在cpp目次下新建cmake文件,文件名固定,不可修改: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.18.1)# Declares and names the project.project("jniproject")# Creates and names a library, sets it as either STATIC# or SHARED, and provides the relative paths to its source code.# You can define multiple libraries, and CMake builds them for you.# Gradle automatically packages shared libraries with your APK.add_library( # Sets the name of the library.        jniproject        # Sets the library as a shared library.        SHARED        # Provides a relative path to your source file(s).        native-lib.cpp)# Searches for a specified prebuilt library and stores the path as a# variable. Because CMake includes system libraries in the search path by# default, you only need to specify the name of the public NDK library# you want to add. CMake verifies that the library exists before# completing its build.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)# Specifies libraries CMake should link to your target library. You# can link multiple libraries, such as libraries you define in this# build script, prebuilt third-party libraries, or system libraries.target_link_libraries( # Specifies the target library.        jniproject        # Links the target library to the log library        # included in the NDK.        ${log-lib})cmake_minimum_required:指定cmake的最小版本
project("jniproject"):cmake工程名称
add_library:添加库。jniproject:库名,SHARED:表示动态库
8、模块的build.gradle 下设置cmake
android {    compileSdk 32    defaultConfig {        // ...        externalNativeBuild {            cmake {                abiFilters 'armeabi-v7a'                cppFlags "-std=c++11 -frtti -fexceptions -Os -Wall"            }        }        ndk { // "armeabi-v7a", "arm64-v8a"            abiFilters 'armeabi-v7a'        }    }    externalNativeBuild {        cmake {            path file('src/main/cpp/CMakeLists.txt')            version '3.18.1'        }    }}cmake 指定c++11标准,而且cpu架构必要指定为 armeabi-v7a,如果不指定cpu架构,默认的cpu架构是:arm64-v8a
9、编译
编译之后天生 so 库:
1.png 10、加载动态库
public class JNI {    static {        // 导入动态库        System.loadLibrary("jniproject");    }    ...}11、链接动态库
public class MainActivity extends AppCompatActivity {    private ActivityMainBinding binding;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        binding = ActivityMainBinding.inflate(getLayoutInflater());        setContentView(binding.getRoot());        // Example of a call to a native method        TextView tv = binding.sampleText;        tv.setText(new JNI().stringFromJNI());    }}五、天生头文件

头文件代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_nobug_jniproject_JNI */#ifndef _Included_com_nobug_jniproject_JNI#define _Included_com_nobug_jniproject_JNI#ifdef __cplusplusextern "C" {#endif/* * Class:     com_nobug_jniproject_JNI * Method:    stringFromJNI * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_nobug_jniproject_JNI_stringFromJNI  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif该文件可以资助步调员快速完成JNI接口的步调编写。
天生该文件只必要一个下令即可天生。
第一步:切换目次
cd .\app\src\main\java\第二步:拷贝Java本地接口文件的引用
3.png 复制出来的内容是:com.nobug.jniproject.JNI
第三步:实验下令天生头文件
javah com.nobug.jniproject.JNI六、快速创建JNI函数

除了使用 javah 天生JNI代码,还可以使用快捷键可以直接天生。
首先界说好native函数,按下快捷键 alt+enter,如下图:
选择"Create JNI function for xxxx",可以快速天生JNI代码。
[本章完...]
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-22 01:30, Processed in 0.168022 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表