参考:https://www.cnblogs.com/Reverse-xiaoyu/p/14110735.html
https://www.jb51.net/article/169438.htm
新建一个JNITest.java 文件
内容如下:
package com.example.rabbit;
public class JNITest {
public native String getJNIString();
}
1、打开android studio自带命令行终端,使用javac编译JNITest.java(如提示找不到javac命令则排查下是否是Path环境变量设置有问题,增加jdk执行文件目录C:\Program Files\Java\jdk1.8.0_202\bin;)
E:\Linux\Android\AndroidStudioProjects\Rabbit\app\src\main\java\com\example\rabbit>javac JNITest.java
编译完成后,JNITest.java同级目录下生成JNITest.class文件
2、命令行终端回退目录到app/src/main下面,使用javah生成 .h 文件
E:\Linux\Android\AndroidStudioProjects\Rabbit\app\src\main>javah -d jni -classpath ./java com.example.rabbit.JNITest
命令执行完毕后会在app/src/main目录下面生成一个jni文件夹,文件夹下面有一个com_example_rabbit_JNITest.h文件
该头文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_example_rabbit_JNITest */
#ifndef _Included_com_example_rabbit_JNITest
#define _Included_com_example_rabbit_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_rabbit_JNITest
* Method: getJNIString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_rabbit_JNITest_getJNIString
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
1、在jni目录下创建c/c++ source file,这里创建JNITest.cpp
cpp中实现头文件中定义的方法,内容如下:
#include
#include
#include "com_example_rabbit_JNITest.h"
JNIEXPORT jstring JNICALL Java_com_example_rabbit_JNITest_getJNIString
(JNIEnv *env, jobject)
{
return env->NewStringUTF("Hello From JNITest Function(getJNIString)");
}
这一步可以在工程下的 jni 目录创建 Android.mk 文件,使用android studio下载的NDK工具编译上一步的cpp文件,也可以在linux环境使用NDK编译,我这里选择在linux下编译cpp
1、linux下安装NDK工具android-ndk-r10e-linux-x86_64.bin
2、将JNITest.cpp和com_example_rabbit_JNITest.h拷贝到编译目录下
3、将jni需要的头文件拷贝到编译目录下(jni.h、jni_md.h等等,在jdk安装目录include下面)
4、在编译目录下创建jni文件夹,编写Android.mk和Application.mk,Android.mk如下所示
#编译动态库
LOCAL_PATH := $(PWD) #$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libJNITest
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS := -lm -llog -lc -lz -ljnigraphics -landroid -lstdc++ -ldl
LOCAL_CFLAGS := $(L_CFLAGS)
LOCAL_SRC_FILES := $(LOCAL_PATH)/JNITest.cpp
LOCAL_C_INCLUDES := $(INCLUDES)
LOCAL_C_INCLUDES += /home/runoob/work/my_project/ndk/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/win32
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/win32/bridge
include $(BUILD_SHARED_LIBRARY)
5、使用ndk-build编译生成libJNITest.so文件(arm64-v8a)
1、app\src\main目录下创建jniLibs目录,在jniLibs下创建arm64-v8a目录,将so文件放在该目录下
2、修改app目录下的build.gradle文件,添加sourceSets字段指定so目录
apply plugin: 'com.android.application'
android {
compileSdkVersion 31
buildToolsVersion "32.0.0"
defaultConfig {
applicationId "com.example.rabbit"
minSdkVersion 15
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
//jniLibs.srcDirs 'src/main/jniLibs' //把libs文件夹当成jniLibs文件夹,可以直接用so库了
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
static {
System.loadLibrary("JNITest");
}
TextView text1 = (TextView)findViewById(R.id.textView);
JNITest jniTest = new JNITest();
text1.setText(jniTest.getJNIString());