一、通过CmakeList.txt来创建jni
ps:在android studio中可以通过创建一个Native C++工程来快速创建一个jni文件,实现java调用c++方法。这里选择自己手动创建jni文件。
步骤如下:
① 新建一个empty Activity项目,编写MainActivity如下:
package com.hoho.android.jni_test;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textureView = findViewById(R.id.tv);
textureView.setText(stringFromJNI());
}
public native String stringFromJNI();
}
② 在app/src/main目录下新建一个jni目录:
新建完成后,会发现app/src/build.gradle下面会多出下面这些话:
sourceSets {
main {
jni {
srcDirs 'src\\main\\jni'
}
}
}
③ 在jni目录下创建两个文件:CmakeList.txt和native-lib.cpp文件:
(1)CmakeList.txt
cmake_minimum_required(VERSION 3.10.2)
project("opengl_test")
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).
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 )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
(2)native-lib.cpp
静态方法(包名+类名+函数名):
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_hoho_android_jni_1test_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
动态方法(函数自己声明,但是需要重写JNI_OnLoad方法):
#include <jni.h>
#include <string>
#define CLASS_NAME "com/hoho/android/jni_test/MainActivity"
extern "C" {
//函数声明
JNIEXPORT jstring stringFromJNI(JNIEnv* env, jobject /* this */);
}
jstring stringFromJNI(JNIEnv* env,jobject /* this */) {
std::string hello = "Hello from momoko";
return env->NewStringUTF(hello.c_str());
}
// 函数映射
static JNINativeMethod gMethods[] =
{
{ "stringFromJNI", "()Ljava/lang/String;", (void*) stringFromJNI},
};
jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
return JNI_ERR;
//在这个java类中声明了本地方法,所以这里写这个方法的全路径
jclass clazz = env->FindClass(CLASS_NAME);
if(clazz != NULL) {
//注册本地方法到VM表中
if(env->RegisterNatives(clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) < 0)
return JNI_FALSE;
}
return JNI_TRUE;
}
④ 转换工程配置:
右键main文件夹,选择Link C++ Project with Gradle,我们这里选择使用Cmake的方式,project Path处选择jni目录下的CmakeList.txt。
执行完后,会发现app/src/build.gradle下面会多出下面这些语句:
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.10.2'
}
}
最后的目录结构如下:
二、使用Android.mk来编译native文件
将上述CmakeList.txt换成Android.mk文件,然后在点击Link C++ Project with Gradle时选择使用ndk-build的方式即可,其余步骤相同。Android.mk编写如下:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native-lib
LOCAL_SRC_FILES := native-lib.cpp
include $(BUILD_SHARED_LIBRARY)
执行完后,会发现app/src/build.gradle下面会多出下面这些语句:
externalNativeBuild {
ndkBuild {
path file('src/main/jni/Android.mk')
}
}
OK,以后可以拿这个当编写jni文件的模板,实现java调用c++方法。
参考链接:使用Android studio开发jni,并实现单步调试c/c++代码_ching的专栏-CSDN博客_android jni 调试