本文使用最新的JNI构建工具CMake完成
通过这篇文章,你讲学习到:
package com.bendeng.jnindk;
/**
* @author: dwj
* @date: 2019/4/10 15:39
* @desc:
*/
public class JNI {
// Used to load the 'test-lib' library on application startup.
static {
// 一定要加这一句,否不会生成so库
System.loadLibrary("test-lib");
}
}
#include "../header/test.h"
int return_value(void)
{
return 5;
}
void print_value()
{
cout<<"successful call this method"<
#include
using namespace std;
int return_value(void);
void print_value();
int add(int x, int y);
int mul (int x, int y);
cmake_minimum_required(VERSION 3.4.1)
#so库的输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})
#1. 添加自己的so库test-lib
add_library( # Sets the name of the library.
test-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/include/test.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
#2.添加链接
target_link_libraries( # Specifies the target library.
test-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
package com.bendeng.jnindk;
/**
* @author: dwj
* @date: 2019/4/10 15:39
* @desc:
*/
public class JNI {
// 此参数被C++赋值
public int number;
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("test-lib");
}
/**
* 通过在C++里面改变field参数值number
*/
public native void changeFieldValue();
/**
* 通过在C++里面调用java方法
*/
public native double callJavaMethod();
// 此方法被C++调用
public double max(double d1, double d2) {
return d1 > d2 ? d1 : d2;
}
/**
* 调用C++封装的so方法
*/
public native int returnValue();
}
#include
#include
#include
#include "header/test.h"
extern "C" JNIEXPORT void
JNICALL
Java_com_bendeng_jnindk_JNI_changeFieldValue(JNIEnv *env, jobject jobj) {
// 获取jobj中class对象
jclass clazz = env->GetObjectClass(jobj);
// 获取字段number的ID,最后一个参数是签名
jfieldID id_number = env->GetFieldID(clazz, "number", "I");
// 获取字段的值
jint number = env->GetIntField(jobj, id_number);
// 打印默认的初始值
std::cout << "number=" + number << std::endl;
// 给number赋新的值
env->SetIntField(jobj, id_number, 100);
}
extern "C" JNIEXPORT jdouble
JNICALL
Java_com_bendeng_jnindk_JNI_callJavaMethod(JNIEnv *env, jobject jobj) {
// 获取jobj中class对象
jclass clazz = env->GetObjectClass(jobj);
// 获取方法max的ID,最后一个参数是签名
jmethodID id_max = env->GetMethodID(clazz, "max", "(DD)D");
// 获取字段的值
jdouble max_value = env->CallDoubleMethod(jobj, id_max, 1.2, 3.4);
return max_value;
}
extern "C" JNIEXPORT jint
JNICALL
Java_com_bendeng_jnindk_JNI_returnValue(JNIEnv *env, jobject jobj) {
// 此方法是调用test.cpp封装的so里面的方法
return return_value();
}
配置CMakelist.txt文件,构建goodutil库,两步如下:
cmake_minimum_required(VERSION 3.4.1)
#so库的输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})
#1. 添加自己的so库native-lib
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
#2.添加链接
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
cmake_minimum_required(VERSION 3.4.1)
#1.配置第三方so库.h头文件路径
include_directories(src/main/cpp/header)
#指定so库输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
#2.添加第三方库
add_library(test-lib SHARED IMPORTED)
#3.添加库的路径
set_target_properties(test-lib
PROPERTIES IMPORTED_LOCATION
${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libtest-lib.so)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
#4.添加链接
target_link_libraries( # Specifies the target library.
native-lib
test-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
sourceSets {
main {
jni.srcDirs = []
jniLibs.srcDirs = ['libs']
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.bendeng.jnindk"
minSdkVersion 18
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// externalNativeBuild {
// cmake {
// cppFlags ""
// }
// }
// ndk{
// abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'
// }
sourceSets {
main {
jni.srcDirs = []
jniLibs.srcDirs = ['libs']
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// externalNativeBuild {
// cmake {
// path "CMakeLists.txt"
// }
// }
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.+'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
参考资料:https://blog.csdn.net/hukou6335490/article/details/83687419
https://blog.csdn.net/hjj378315764/article/details/79834352
https://blog.csdn.net/yuanzhihua126/article/details/78992068
https://blog.csdn.net/wzhseu/article/details/79683045