一、前言

本文将创建一个 HelloWorld 程序,程序功能很简单,就是一个 jni 方法返回"HelloWorld "字符串,然后界面展示。 jni 中涉及动态注册和静态注册,在 实际开发过程中动态注册用的比较多,本工程 采用动态注册方式实现。 Android Studiojni代码可以通过 ndk 或者 cmake 工具链进行编译。 在本工程中两种方式都进行了配置测试。

本文中的Demo工程可以作为jni开发过程中最基础的模板。

二、前置准备

在开发之前请安装好 Android Studio 开发工具,并配置好 cmakendk 工具。 Android Studio 中 cmake和ndk配置可参考:

安卓ndk开发实战(1)Android Studio 中配置 ndk 和 cmake 工具

三、开发jni程序HelloWorld

(1)、Android Studio创建工程JNIDemoHelloWorld01的简单Activity应用

(2)、在工程根目录app/src/main中创建cpp目录保存jni代码

(3)、在cpp目录下创建HellWorld.cpp文件已经对应的cmake编译配置、ndk编译配置文件,如下所示:

(4)、在工程中的MainActivity中添加native方法,该方法返回字符串。 如下所示:

 private  static native String  helloWorld();

(5)、HellWorld.cpp中实现jni方法helloWorld,以下是关键代码:

//jni方法hellWorld对应的逻辑实现static jstring myhelloWorld(JNIEnv *env, jclass cls) {    return env->NewStringUTF("HelloWorld");}//static JNINativeMethod jniHelloWorl[] = {        {                "helloWorld",                "()Ljava/lang/String;",                (void *) myhelloWorld        }};static bool registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *jniMethods,                                  int methods) {    jclass clazz = env->FindClass(className);    if (clazz == NULL) {        return false;    }
    return env->RegisterNatives(clazz, jniMethods, methods) >= 0;}//JNI_OnLoad里面完成jni方法的注册JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {    int jniMethodSize = sizeof(JNINativeMethod);    JNIEnv *env = NULL;    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {        return -1;    }    if (!registerNativeMethods(env, CLASS_NAME, jniHelloWorl, sizeof(jniHelloWorl) /                                                              jniMethodSize)) {        return -1;    }    LOGD("JNI Loaded");
    return JNI_VERSION_1_6;}

(6)、分别配置Android.mk文件和CMakeLists.txt

    Android.mk文件配置如下:​​​​​​​

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := helloworldLOCAL_CFLAGS += -Wno-error=format-security -fpermissive -O2LOCAL_CFLAGS += -fno-rtti -fno-exceptionsLOCAL_CPPFLAGS += -std=c++11
LOCAL_SRC_FILES := HelloWorld.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

CMakeLists.txt配置如下:

cmake_minimum_required(VERSION 3.4.1)project(helloworld)
add_definitions(-std=c++11)
set(${PROJECT_NAME}_SOURCES        HelloWorld.cpp        )
add_library(${PROJECT_NAME}        SHARED        ${${PROJECT_NAME}_SOURCES})
target_link_libraries(${PROJECT_NAME} log)

(7)、将Android.mk和CMakeLists.txt加入build.gradle文件

在实际选择ndk方式还是cmake方式编译的时候,可以在build.gradle中注释掉不需要的编译方式即可。如下是build.gradle的完整内容:

plugins {    id 'com.android.application'}android {    compileSdkVersion 30    buildToolsVersion "30.0.2"    defaultConfig {        applicationId "com.android.jnidemo01"        minSdkVersion 23        targetSdkVersion 30        versionCode 1        versionName "1.0"        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"        externalNativeBuild {            //cmake编译方式参数配置            cmake {                arguments "-DCMAKE_BUILD_TYPE=Release  -DDEBUG=1"            }            //ndk编译参数配置            ndkBuild {                abiFilters 'armeabi-v7a', 'arm64-v8a'            }        }    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'        }    }    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }    //以下配置比较重要,cmake如果不注释就是使用cmake编译    //ndkBuild如果不注释就是使用ndk方式编译    externalNativeBuild {//        cmake {//            path file('src/main/cpp/CMakeLists.txt')//        }        ndkBuild {            path file("src/main/cpp/Android.mk")        }    }}dependencies {    implementation 'androidx.appcompat:appcompat:1.2.0'    implementation 'com.google.android.material:material:1.2.1'    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'    testImplementation 'junit:junit:4.+'    androidTestImplementation 'androidx.test.ext:junit:1.1.2'    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'}

(8)、加载helloworld动态库

MainActivity类中,加入如下代码完成helloworld动态库的加载

static {    System.loadLibrary("helloworld");}

(9)、调用helloWorld方法测试验证

Demo比较简单,直接调用jni方法,然后界面显示返回的字符串。测试关键代码如下:​​​​​​​

 textViewShowMsg=(TextView)findViewById(R.id.textViewShowMsg);textViewShowMsg.setText("测试jni返回结果:"+helloWorld());

手机运行结果如下:

如果你需要本文中的Demo工程,请访问如下地址进行下载:

https://gitee.com/ZL007/jnidemo01-hello-world

如果喜欢本公众号的技术文章,记得关注一下"卓码空间",顺便点点赞。

安卓jni(ndk)开发实战(2)开发jni第一个HellowWorld程序相关推荐

  1. [精简]RuoYi开发实战-搭建开发环境

    文章目录 简介 说明 RuoYi环境准备 JDK 安装docker mysql安装 redis 6.2安装 下载源码 数据库初始化 Redis配置 数据源配置 Logback报错解决 测试后端是否启动 ...

  2. 在Rockchip RK3399 Pro开发板上跑通第一个Qt程序

    在Rockchip RK3399 Pro开发板上跑通第一个Qt程序 准备工作:将Qt从Windows移植到Linux 一.交叉编译器的准备 下载交叉编译工具 安装交叉编译工具 二.交叉编译Qt库 三. ...

  3. 《微信小程序开发实战》学习笔记chapter1微信小程序人门

    Chapter01 微信小程序入门 1. 微信小程序介绍 1.1 什么是微信小程序 微信小程序是腾讯于2017年1月19日推出的一种不需要安装即可在微信平台上使用的应用.微信小程序和微信的原生功能应用 ...

  4. Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码

    01 Windows应用程序分类 1.应用程序分类 控制台程序Console DOS程序,本身没有窗口,通过Windows DOS窗口执行(借的的操作系统的窗口) 窗口程序 拥有自己的窗口,可以与用户 ...

  5. 图文详述:下载安装JDK,搭建Java开发环境,并运行第一个Java程序

    文章目录 前言 一.Java 三大版本 二.JDK.JRE和JVM 三.Java 开发准备 1. JDK 下载 2. JDK 安装 3. JDK 配置 (Java 开发环境搭建) 4. JDK 测试 ...

  6. 安卓开发之Java基础(1)——第一个Java程序

    1.计算机软件和硬件:  ①计算机软件可以使计算机按照事先预定好的顺序额完成特定的功能,按照功能可以划分为:系统软件{DOS(Disk Operating System).Windows.Linux. ...

  7. Android之JNI NDK错误找不到jni.h 小黄x Type xxx could not be resolved

    为什么出现这样的问题,按道理设置NDK路径之后,可以自己找到才对啊,现在没有时间去跟,等有空再研究,要是有谁知道分享一下. 先解决再说,项目急. 网上查了一下,都是添加路径,但还是不行.. 我用的是. ...

  8. Python——Web2py开发实战:开发一个自己的网站(新手入门级)

    目录 一.web2py 二.使用步骤 1.找到一个可以帮助网站运营的工具--pythonanywhere 1)创建账户: 2)创建网站 3) 网站管理 2.我的开端 1)删除example app 2 ...

  9. redmine二次开发实战--windows开发环境搭建

    目录 目录 前言 一.安装redmine 1.下载安装包 2.安装程序 二.开发工具 总结 目录 前言 redmine是基于ruby on rails架构的一款项目管理软件,虽然ruby在window ...

最新文章

  1. 从AdventureWorks学习数据库建模——保留历史数据
  2. 自动化才能解放安全团队
  3. ubuntu下安装java和tomcat安装
  4. C++ Primer 5th笔记(8)chapter8 类:IO库-流的状态
  5. C++之const修饰得到是谁
  6. xml建模包括以下_为什么要进行建模仿真?
  7. capture 部分元器件编号_十大电子元器件及其相关基础知识
  8. 2017.9.27 可持久化并查集 失败总结
  9. 守护线程和非守护线程
  10. 大厂内部资料 | Redis 性能优化的 13 条军规!
  11. 从零学React Native之11 TextInput
  12. EntityFramework 元数据 设计分析
  13. u盘修复计算机系统,如何使用u盘修复系统
  14. 让游戏沉浸感炸裂的实时3D音效技术原理与实践(上)
  15. 数字温度传感器DS18B20中文资料(含读写程序)-
  16. 椭圆机的减肥效果怎么样
  17. 什么是WebP图片格式?如何在线把Webp格式转换为JPEG格式?
  18. 图像显著性论文(六)—Saliency Filters Contrast Based Filtering for Salient Region Detection
  19. 2021年全国大学生电子设计大赛(一)赛题解析与预测
  20. Kaggle手写数字识别(Digit Recognizer)记录

热门文章

  1. win11 电脑无法连接 win10 USB共享打印机
  2. 360浏览器扩展搜不到AdGuard去广告插件问题处理
  3. Redis之最细命令介绍
  4. html中row位置居中,如何快速找到html和row text对应的位置?
  5. 校园网及入网计算机管理制度,校园网管理制度
  6. 如何使用CMD查询电脑连接的无线网络密码或如何查看电脑连接的无线网络密码
  7. Objective-C(十九、通知-消息发送模式之中的一个)——iOS开发基础
  8. --->>>MySQL常用命令关键点
  9. 史上最烂的开发项目长啥样:苦撑12年,600多万行代码...
  10. 人工智能统治围棋?棋士一文不值?