利用IDEA进行JNI开发:使用NDK生成Linux平台下的so文件
使用NDK生成Linux平台下的so文件和使用MinGW生成Windows平台下的dll文件前半部分是一样的,都是用javah生成头文件,再根据头文件编写.c(C文件)或者.cpp文件(C++文件),最后利用这个文件生成各自的库先下载好自己平台下的NDK文件,下载地址:NDK 下载 流程如下:1.编写包含native方法的类2.将此类使用javah生成对应的头文件(推荐下...
使用NDK生成Linux平台下的so文件和使用MinGW生成Windows平台下的dll文件前半部分是一样的,都是用javah生成头文件,再根据头文件编写.c(C文件)或者.cpp文件(C++文件),最后利用这个文件生成各自的库
先下载好自己平台下的NDK文件,下载地址:NDK 下载
流程如下:
1.编写包含native方法的类
2.将此类使用javah生成对应的头文件(推荐下里面我总结的内容:IDEA开发,Jni中javah使用方式的探索)
3.利用此头文件编写.c或者.cpp文件:这一步很简单
这是随便写的一个native方法生成的.h头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class test_ndkdemo_MainActivity */
#ifndef _Included_test_ndkdemo_MainActivity
#define _Included_test_ndkdemo_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: test_ndkdemo_MainActivity
* Method: getStr
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_test_ndkdemo_MainActivity_getStr//看这里看这里看这里,我写的native在头文件里的表现形式
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
之后直接新建文件命名为.c或者.cpp格式,然后#include"你生成的类名.h",实现你.h里只是单单声明的方法,比如这样
#include"test_ndkdemo_MainActivity.h"//导入你的头文件
JNIEXPORT jstring JNICALL Java_test_ndkdemo_MainActivity_getStr//然后实现里面的具体内容
(JNIEnv *env, jobject obj){
char buf[128]="test";
return (*env)->NewStringUTF(env,buf);
}
4.使用NDK:使用NDK你需要编写一个Android.mk的文件,有过Linux下使用gcc命令的看到mk应该会想到make和make file相关的内容,Android.mk的底层也是他们
编写Android.mk的资料我推荐这个,Android.mk详解
在编写好之后我们就可以使用NDK工具了(其实是使用NDK路径下的ndk-build.cmd文件,有兴趣的可以去找找,然后把编译相关的文件拷过来尝试就在那个目录下执行这个命令)
比如我的是
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test_ndkdemo_MainActivity.c
include $(BUILD_SHARED_LIBRARY)
很简单的- -。
不过请读者老爷们注意几点:你的.h,.c,.cpp和Android.mk得放一个文件夹下(不放也可以,你路径在Android.mk里多写几个字母也行);要是还要使用其他的库的话记得在Android.mk添加进去
然后,我们就不跑到NDK安装路径下使用ndk-build.cmd命令了,我们使用前面介绍过的一键生成方式
之后随便选你Android.mk所在目录下随便一个文件执行此External Tools就行了。
剩余几点想说的
1.生成了两个文件夹,不知道为什么,有读者知道的话请告知一下
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
2018.1.8
后面研究SO文件的时候,竟然偶然得知了这个答案
使用ndk生成的so文件时会经过strip这样一个操作,strip会将so里动态链接库末尾的.symtab和.strtab这两个section去掉。
可以在\obj\local下找到未经过strip的.so文件。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
2.Gradle在java的同级目录中定义了一个jniLibs的变量用于存放jni的库,记得以前的做法是把jni的库都放在lib目录下,然后声明jniLibs的值
android{
02. sourceSets {
03. main {
04. jniLibs.srcDirs = ['libs']
05. }
06.}
现在很简单了,新建和java同级的目录命名为jniLibs,放入jni的库就能在编译时加入了
3.关于ndk-build.cmd:
更多推荐
所有评论(0)