NDK开发入门

2024-05-08 22:48
文章标签 ndk 入门 开发

本文主要是介绍NDK开发入门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、安装与配置

首先我们在Android Studio下新建一个安卓项目。然后打开Project Structure界面,如下: 

是我的 这里写图片描述

在SDK Location目录下,有SDK和NDK的路径,而这里我们暂时还未下载配置过NDK,故我们需要点击Download Android NDK来进行下载(Android Studio还是很强大的,相比Eclipse能省不少事)。这里Android Studio会下载最新版本的NDK进行安装,默认会下载保存在SDK的路径下。我们在上图中还能看到有一段介绍文字,说SDK以及NDK的路径配置会保存在local.properties文件内,安装完成后我们刷新Project,进local.properties文件查看也能看到SDK与NDK的路径。 
这里写图片描述

这里写图片描述

NDK下载配置完成之后,需要在gradle.properties文件中加上一行:

android.useDeprecatedNdk=true

注意:如果报一下错误。

Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio.  Please switch to a supported build system.Consider using CMake or ndk-build integration. For more information, go to:https://d.android.com/r/studio-ui/add-native-code.html#ndkCompileTo get started, you can use the sample ndk-build script the Androidplugin generated for you at:E:\SwimmingSpace\ndktest\build\intermediates\ndk\debug\Android.mkAlternatively, you can use the experimental plugin:https://developer.android.com/r/tools/experimental-plugin.htmlTo continue using the deprecated NDK compile for another 60 days, set android.deprecatedNdkCompileLease=1570668052257 in gradle.properties

      在gradle.properties文件里把android.useDeprecatedNdk去掉换成android.deprecatedNdkCompileLease=1570668052257就行了

接下来,我们借助强大的Android Studio的插件功能,在External Tools下配置两个非常有用的插件。进入Settings–>Tools–>ExternalTools,点击+号增加。 

这里写图片描述

这里写图片描述

javah -jni命令,是根据java文件生成.h头文件的,会自动根据java文件中的类名(包含包名)与方法名生成对应的C/C++里面的方法名。下面是参数配置及其含义: 
1. Program: $JDKPath$\bin\javah.exe 这里配置的是JDK目录下的javah.exe的路径。 
2. Parametes: -classpath . -jni -d $ModuleFileDir$/src/main/jni $FileClass$ 这里$FileClass$指的是要执行操作的类名(即我们操作的文件),$ModuleFileDir$/src/main/jni表示生成的文件保存在这个module目录的src/main/jni目录下。 
3. Working: $ModuleFileDir$\src\main\java module目录下的src\main\java目录(不是很理解)。 
使用方式:选中java文件—>右键—>External Tools—>javah-jni,将生成jni文件夹以及文件夹下的 包名.类名的.h头文件 (名字过长,我们可以自己重命名)。 

这里写图片描述
ndk -build命令,是根据C/C++文件生成so文件的。下面是参数配置及其含义: 
1. Program: F:\apk\sdk\ndk-bundle\ndk-build.cmd 这里配置的是ndk下的ndk-build.cmd的路径(根据实际情况填写)。 
2. Working: $ModuleFileDir$\src\main\ 
 

在build.gradle中的android添加

    sourceSets {main() {jniLibs.srcDirs = ['src/main/libs']}}

要不为弹出ANR运行错误提示找不到.so库。

二、简单实例

1、创建一个访问本地C/C++方法的java类

package cyh.com.ndk_demo;public class JniTest {static {System.loadLibrary("JniTest");}public static native  String get();
}

     注意JniTest这个Library名字,之后在Android.mk中还会需要用到,要保持一致。该类提供了一个static的native方法,该方法将用来返回一个字符串。然后对该文件执行javah -jni操作,选中java文件—>右键—>External Tools—>javah-jni,生成对应的.h头文件。 

如图,已经根据我们的java类生成了对应的.h文件,文件名为包名_类名.h,里面只有一个方法,返回值为String(jstring),方法名为Java_类的包名_类名_方法名(包名中的分级不是用.而是_),前面两个参数是C++里面必须有的(JNIEnv代表指向JVM的指针,jclass是调用该方法的java对象),第三个就是我们java类的方法里面的参数Object。注意,这是java函数与C++函数对应的静态注册方法,即通过特定的规则来写,此处方法名可以随意起名字,然后还可以用动态注册的方式关联两个方法(显然,静态注册要简单一些)。 
2、然后我们新建一个C文件,取名为test.c,写上需要include的文件,从.h文件中复制方法过来(方法名、参数类型、返回值等必须一致!血与泪的教训)。 

至此,.h文件和c文件均已完成,接下来还需要在这个jni目录下增加两个文件,Android.mk和Application.mk。 
Android.mk,注意LOCAL_MODULE的值与之前的名字相对应,LOCAL_SRC_FILES的值写c++文件的名字,这两个值成对设置,可设置多组。(:=是赋值的意思,$是引用某变量的值。)

  1. LOCAL_PATH := $(call my-dir)     // 设置当前的编译目录(Android.mk所在的目录) 
  2. include $(CLEAR_VARS)            // 清除LOCAL_XX变量(LOCAL_PATH除外)
  3. LOCAL_MODULE := JNI_ANDROID_TEST  // 指定当前编译模块的名称  
  4. LOCAL_SRC_FILES := jnitest.cpp    // 编译模块需要的源文件
  5. include $(BUILD_SHARED_LIBRARY) // 指定编译出的库类型,BUILD_SHARED_LIBRARY:动态库;BUILD_STATIC_LIBRARY:静态库, BUILD_EXECUTEABLE指:可执行文件

 

       Application.mk,APP_ABI有四种类型(默认armeabi),armeabi、armeabi-v7a、x86、mips,设置时以空格隔开,all表示所有。该文件中有个可选配置的APP_MODULES,类似于上面Android.mk文件中的LOCAL_MODULE,以空格隔开,且会覆盖掉Android.mk文件中的LOCAL_MODULE设置(比如Android.mk文件中的写了两个jni库的配置,LOCAL_MODULE := JNI1、LOCAL_MODULE := JNI2,而Application.mk中设置的APP_MODULES := JNI1,则只能生成JNI1的so文件,要生成JNI2的so文件的时候会报错,除非写成APP_MODULES := JNI1 JNI2,这里我们直接省略默认使用Android.mk中的)。
     APP_ABI := all

接下来我们需要对C文件执行ndk-build操作,使用方式:选中C/C++文件—>右键—>ExternalTools—>ndk-build,生成相应的so文件。 

如图,在main/libs目录下生成了多个so文件,名字为lib+我们指定的库名,同时还生成了obj文件夹。

3、在MainActivity中调用C方法即可。

    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//打印信息Log.e("Message", JniTest.get());}

若更改c文件名称或者内容,出现make: *** No rule to make target `jni\test.c', needed by `obj/local/arm64-v8a/objs/JniMethod/test.o'.  Stop.错误!

可以手动删除libs和obj 文件夹,即可重新生成.so库。

以上内容大部分来自网络,注意参考:https://blog.csdn.net/xiaoyu_93/article/details/52870395

这篇关于NDK开发入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/971663

相关文章

企业支付宝账号开发接口教程--JAVA-UTF-8(实际操作完善中...SpringMVC+JSP)

关于即时到账的开发。审核通过。简单测试如下。 希望看的可以收藏或者赞一下哦。 1.拥有自己的支付宝企业账号。去产品商店选择适合自己的方案。并签约合同。 2.选择合适的商家收款产品并去签约。填写相应的信息 3.在商家服务会有PID和KEY是关键的东西。 4.选择自己签约的产品类型,下载对应的接口api与测试代码 即时到账收款 --alipaydirect 网银支付 -

借助百度云中的百度人脸识别用Java开发一个人脸识别

百度应用创建步骤官网图文提供:http://ai.baidu.com/docs#/Begin/top 获取Token图文步骤官网已提供:http://ai.baidu.com/docs#/Auth/top  人脸检测V3在线体验:https://www.ydxiaoshuai.cn/xai/rest/face/index 人脸检测V3(JavaAPI)示例代码地址:【人脸检测】V3版的你

repo使用总结—从入门到入门

文章目录 1 what's repo2 官方文档Repo 命令参考资料help 帮助init 初始化sync 同步所有项目文件upload 提交更改diffdownloadforallprunestart 创建本地分支Example:创建三个分支test-1,test-2,test-3 statusbranchesabandonExample:删除本地分支test-3 后续在使用中遇到问题

STM32 TIM 多通道互补PWM波形输出配置快速入门

platform:stm32f10xxx lib:STM32F10x_StdPeriph_Lib_V3.5.0 前言 在做三相逆变的时候,需要软件生成SVPWM波形,具体的算法需要产生三对互补的PWM,这样可以驱动六个开关元件,stm32f103中的TIM1高级定时器支持产生三路互补PWM波形,下面进一步学习。 PWM产生的原理 TIM1的OC模块,可以产生PWM波形,具体步骤; 寄存器

STM32 TIM1高级定时器配置快速入门

layout: post tags: [STM32] comments: true 文章目录 layout: post tags: [STM32] comments: true重点内容时基单元计数模式 重点内容 不管是基于标准库还是直接操作寄存器,因为TIM定时器的功能比较多,这里单纯只从定时器的角度进行学习,这里需要重点关注的地方应该有以下几点: 定时器时钟频率的计算

STM32 时钟树配置快速入门

layout: post tags: [STM32] comments: true 文章目录 layout: post tags: [STM32] comments: true为什么要了解时钟树?树的根标准库的时钟配置外部时钟源16MSetSysClockTo72patch 其他细节 为什么要了解时钟树? 最近项目开发的时候,外部时钟源是16MHz,结果配置错了系统时钟,

高手支招!快速解决复杂的嵌入式人机界面开发

显示屏 智能化的今天,越来越多的产品更加注重用户体验了,很多电子产品上都会配备一款显示屏,以提高产品的档次,同时也方便人机交互。这里,复杂的人机界面设计在嵌入式开发中就成了一个痛点。 目前,大多数电子产品使用的显示屏,还是以LCD(液晶显示器)为主。 用LCD开发一款酷炫界面的产品,通常有两种方法:1.用现成GUI技术实现;2.基于LCM模组二次开发;两种方式各有各的特点。 LCD(液晶显示器

高手常用的3个开源库,让单片机开发事半功倍

点击上方“小麦大叔”,选择“置顶/星标公众号” 福利干货,第一时间送达 大家好,我是小麦,日志系统在系统开发和调整过程中的重要性, 大家应该都清楚,特别是项目出问题之后,却没有日志可以帮忙定位问题,就非常令人痛苦。 因为我们不可能一直通过调试器去单步调试程序,所以设备的运行日志显得尤为重要。 通常我们对日志有这些要求: 不同的日志级别(Debug,Warning, Info, Error, Fa

bimface开发实战-vue版

效果 演示地址 框架 bimface + vue3.0 代码地址 gitee地址 使用 yarn install yarn serve

Android JNI开发五: JNI字符串的处理

JNI 字符串处理 1. NewStringUTF 创建字符串 jstring NewStringUTF(const char *utf) {return functions->NewStringUTF(this,utf);}参数说明:-utf: 字符串说明:通过调用NewStringUTF函数,会构建一个新的java.lang.String字符串对象。这个新创建的字符串会自动转换成Java