android JNI 开发之—ndk-build编译so库

你还在用ndk-build编so库,放弃吧,快来用cmake编译,cmake简直好用到不行,参考android JNI 开发之—cmake编译so库

本文会学习到一个简单的jni工程,类似于hello world,从最基础的概念到最后实现,中间会和大家一步一步学习,文章中参考的博文都是解决问题的方法,本人小白,如有错误,还请各位大佬指出,不胜感激。

实验环境:
工具:AS
包名:ryd.gyy.anative

基础知识

JNI:

java本地接口(Java Native Interface),就是Java和C/C++相互通信的接口。

由于java执行效率比较低,而C/C++执行效率高,所以在AS中需要导入C/C++文件,jni就是连接java和C/C++之间的纽带。

NDK:

Native Develop Kit,在AS上用于C/C++开发的工具集。

Android NDK 是一套允许您使用C/C++实现部分应用的工具集。在开发某些类型应用时,这有助于您重复使用C/C++编写的代码库,也就是so库。

安装与配置

安装NDK:
在这里插入图片描述
第一次安装点击Download,安装成功之后如上图所示,NDK默认安装位置在SDK的路径下,可以在local.properties中查看。
在这里插入图片描述
NDK下载配置完成之后,需要在gradle.properties文件中加上一行(为了防止 so 库兼容错误):

android.useDeprecatedNdk=true

新建项目

勾选上Include C++ support
在这里插入图片描述
项目会自动生成cpp文件和CMakeLists.txt
在这里插入图片描述

创建JNI文件

创建一个 JNITest.java 的一个类:

public class JNITest {
    
    //创建一个 native 方法
    public native static String get();
}

若创建完后出现如下问题,即get显示红色
在这里插入图片描述
进入setting—》Plugins—》NDK不打勾,重启AS即可
在这里插入图片描述

生成C/C++头文件

在AS控制台Terminal进入JNITest.java所在的目录执行

javac -encoding UTF-8 JNITest.java

在这里插入图片描述
正确生成后可以看到
在这里插入图片描述
-------------------------------------------我是分割线-----------------------------------------------
这里是我遇到的问题,没有问题的可以跳过。

问题一:执行javac出现下图
在这里插入图片描述
解决:首先确认下是否有配置好jdk的环境变量,在cmd输入javac,正确配置之后可以看到输出一大段命令详解。
笔者具体问题:AS没有配置jdk,配置之后可以在cmd看到命令详解,但是在AS控制台Terminal还是会出现上图内容,解决方法是重启电脑,之后就OK了。

问题二:使用javac JNITest.java来生成.class文件,出现下图内容
在这里插入图片描述
解决:使用javac -encoding UTF-8 Test.java来生成C/C++头文件
可以参考:错误:编码GBK的不可映射字符

-------------------------------------------我是分割线-----------------------------------------------

生成h头文件

在AS的Terminal控制台上面回退目录到app/src/main,然后执行下面命令

javah -d jni -classpath ./java ryd.gyy.anative.JNITest

在这里插入图片描述
正确生成后可以看到
在这里插入图片描述
javah:生成h文件
-d:生成的.h的路径,这里是app/src/main
-classpath:用于装入类的路径,后面跟的是类
-jni:生成JNI样式的头文件,后面跟的是包名+类名

比较好理解的写法:javah -classpath 类的路径 -d 存放路径 -jni 包名+类名
大家可以参考这篇,讲的很详细Javah提示未找到 …的类文件

创建C/C++文件

首先先把 setting—》Plugins—》NDK打勾,AS重启,这样才可以看到C/C++文件

在jni目录下创建一个C/C++ resource文件test.c,要选择C为后缀

#include<jni.h>
#include<stdio.h>
//导入我们创建的头文件
#include "ryd_gyy_anative_JNITest.h"

JNIEXPORT jstring JNICALL Java_ryd_gyy_anative_JNITest_get
  (JNIEnv *env, jclass jclass){
      //返回一个字符串
      return (*env)->NewStringUTF(env,"This is my first NDK Application");
 }

这个方法是我们从头文件中复制过来的(方法名、参数类型、返回值等必须一致!)
在这里插入图片描述

创建.mk文件

Android.mk文件:这里我是从其他地方直接复制过来然后修改的

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

LOCAL_MODULE := JNITest
LOCAL_SRC_FILES := test.c
include $(BUILD_SHARED_LIBRARY)

LOCAL_MODULE:jni文件名
LOCAL_SRC_FILES:c++文件的名字

Application.mk文件:这里我是从其他地方直接复制过来然后修改的

APP_ABI := all

all:在所有的文件里面生成so库,也就是下图的4个
在这里插入图片描述

传统方法ndk-build编译生成so库

进入Settings–>Tools–>ExternalTools,点击+号增加
在这里插入图片描述
ndk -build命令,是根据C/C++文件生成so文件的:
E:\sdk\ndk-bundle\ndk-build.cmd 这里配置的是ndk下的ndk-build.cmd的路径(根据实际情况填写)
working directory按照图中的来添加,不变
使用方式:选中C/C++文件—>右键—>ExternalTools—>ndk-build,可以看到main文件夹下生成libs文件夹以及多个so文件,如上图所示。

手动设置生成so库的路径

在build.gradle文件夹的android{}下添加

sourceSets {
        main() {
            jniLibs.srcDirs = ['src/main/libs']//这是AS默认搜索库,
            jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
        }
    }

这里可以参考这篇博客,马上就理解了 原来还有这种操作,libs和jniLibs 还有jni不得不说的关系

动态导入 so 库

在JNITest.java中添加so库,这里写JNITest就可以了,这是lib库的规则。

package ryd.gyy.anative;
public class JNITest {
    // 动态导入 so 库
    static {
        System.loadLibrary("JNITest");//这里写JNITest就可以了
    }
    //创建一个 native 方法
    public native static String get();
}

MainActivity中使用

public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //打印信息
        Log.e("Message",JNITest.get());
    }
}

运行之后查看log
在这里插入图片描述

后文

那么生成的so库,怎么让别人使用呢?请参考 android JNI 开发之—导入so库、jar并调用

啊~终于写完了,有问题评论区见。

作者:鸣人的修炼场
出处:https://blog.csdn.net/baidu_33693586

参考教程:
使用 Android Studio 写出第一个 NDK 程序(超详细)
Android studio 3.0 JNI开发生成so详细教程
NDK开发 从入门到放弃(一:基本流程入门了解)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值