Android studio编写第一个NDK工程的过程详解(附Demo下载地址)

首先附上我的几篇其它文章链接感兴趣的可以看看,如果文章有异议的地方欢迎指出,共同进步,顺便点赞谢谢!!!
Android framework 源码分析之Activity启动流程(android 8.0)
面试必备1:HashMap(JDK1.8)原理以及源码分析
面试必备2:JDK1.8LinkedHashMap实现原理及源码分析
Android事件分发机制原理及源码分析
View事件的滑动冲突以及解决方案
Handler机制一篇文章深入分析Handler、Message、MessageQueue、Looper流程和源码
Android三级缓存原理及用LruCache、DiskLruCache实现一个三级缓存的ImageLoader

1:创建工程和配置NDK

1:如果之前没有下载配置ndk则下载
在这里插入图片描述2:给工程配置ndk路径

方法一:在工程的local.properties文件中添加ndk.dir=D\:\\SoftPath\\Android\\Sdk\\ndk-bundle如下图
在这里插入图片描述方法二:在studio的Project Structure中选择SDK路径
在这里插入图片描述

2:编写JNI程序

第二部分主要是JNI相关操作,因为ndk是基于JNI的

1:创建HelloWord.java类在此类中定义native方法,注意该文件中最好不要有中文字符,我这里加了一些批注方便理解

在这里插入图片描述

public class HelloWord {
    public static native String getString();//从native方法获取一个字符串
    public static native int add(int a,int b);//从native方法做两个数字相加并返回结果
}

2:在Terminal窗口编译HelloWord获取字节码文件javac HelloWord.java注意切换到此文件目录下或者用绝对路径,(你也可以用cmd,这两种方式你都得配置了JDK、NDK的环境变量)

切换目录执行javac HelloWord.java
在这里插入图片描述
执行完javac HelloWord.java 则在当前目录下生成字节码文件
在这里插入图片描述

3:切换目录到 \app\src\main文件目录下执行 javah生成头文件

javah -d jni -classpath D:\WorkSpace\JNIDemo\app\src\main\java myh.com.jnimodel.HelloWord
分析命令:
-d jni:当前目录下创建一个 jni 文件夹
 -classpath D:\WorkSpace\JNIDemo\app\src\main\java myh.com.jnimodel.HelloWord 指向字节码文件的路径

javah指令的详细解释如图
在这里插入图片描述
执行完后会在 main文件夹下创建jni文件夹并生成.h的头文件 ,给文件中声明了HelloWorld中的native方法
在这里插入图片描述强调一点:生成的myh_com_jnimodel_HelloWord.h文件是为了不懂c或者c++的码农方便编写c或c++的代码,可以没有.h文件

4:在jni目录下新建.c或.cpp文件实现.h文件中定义的接口方法

1:选中jni目录右键–》new—》c/c++ Source File, 名字随意我这叫hello.c我用的c语言实现的
在这里插入图片描述 2:实现.h中的就扣方法
在这里插入图片描述在这里解释一下方法中的两个重要参数

  1. JNIEnv *env表示指向JNI环境的指针,通过它来访问JNI提供的接口方法
  2. **jclass **作用相当于Java中的this

hello.c文件的代码

//
// Created by geo on 2019/4/29.
//
#include<jni.h>
#include<stdio.h>
//导入我们创建的头文件
#include "myh_com_jnimodel_HelloWord.h"
JNIEXPORT jstring JNICALL Java_myh_com_jnimodel_HelloWord_getString
  (JNIEnv *env, jclass jclass){
      //返回一个字符串
      return (*env)->NewStringUTF(env,"This is my first NDK Application");
  }

  JNIEXPORT jint JNICALL Java_myh_com_jnimodel_HelloWord_add
    (JNIEnv *env,jclass jclass, jint a, jint b){
        return a+b;
    }

3:ndk编译生成so文件

1:在jni文件下新建 Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := hello// 生成的so文件名称
LOCAL_SRC_FILES := hello.c//编译的c或c++文件
include $(BUILD_SHARED_LIBRARY)

2:在jni文件下新建 Application.mk 指定CPU架构 all代表所有

APP_ABI := all  

最后jni目录有一下四个文件
在这里插入图片描述3:切换目录到jni目录下执行ndk-build生成对应的so文件

在这里插入图片描述执行完ndk-build会在与jni同级目录下生成libs文件夹,该文件夹存放了对应cpu的so文件如下图
在这里插入图片描述

4:调用生成的so文件

1:准备工作:配置Studio加载so文件的路径

第一种方法: 因为Android studio默认加载so的路径是在src\main\jniLibs,在main下新建jniLibs文件夹,将libs里的所有内容都复制到jniLibs下(包括so文件的目录结构)
第二种方法:就是修改Android studio 加载so文件的路径,在model的build.gradle文件中,添加如下代码sourceSets { main { jni.srcDirs = ['libs'] } },注意是android{}标签中添加
在这里插入图片描述2:加载so库
System.loadLibrary("hello")注意hello是上在android.mk中指定的so文件名(即LOCAL_MODULE := hello// 生成的so文件名称),实际上我们生成的so文件前默认会加上lib即libhello.so

在这里插入图片描述运行点击按钮出现如下结果:返回hello.c文件中方法的数据

在这里插入图片描述
到此完毕,最后附上我在编译时遇到的两个问题的解决方案和demo的下载地址
Android NDK 运行错误:java.lang.UnsatisfiedLinkError: Couldn’t load XXX indLibrary returned null

Android studio3.2出现Your project contains C++ files but it is not using a supported native build

Demo传送门

猜你喜欢

转载自blog.csdn.net/weixin_37639900/article/details/89680670