1.随便建一个Kotlin项目JNIDemo 2.java目录下新建包jni 3.jni下新建CMakeLists.txt文件
cmake_minimum_required(VERSION 3.4.1) 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} )3.jni下新建文件native-lib.cpp,这里有动态注册和静态注册,选一个就行
#include <jni.h> #include <string> extern "C" { jstring gun(JNIEnv*env , jobject clazz){ std::string test = "JNITest ++++"; return env->NewStringUTF(test.c_str()); } jstring stringFromJNI(JNIEnv*env , jobject clazz){ std::string test = "main ++++"; return env->NewStringUTF(test.c_str()); } jint RegisterNatives(JNIEnv *env){ jclass clazz = env->FindClass("com/example/jnidemo/JNITest"); jclass clazz2 = env->FindClass("com/example/jnidemo/MainActivity"); if(clazz == NULL){ return JNI_ERR; } JNINativeMethod methods_MainActivity[] = { {"gun", "()Ljava/lang/String;",(void *) gun} }; return env->RegisterNatives(clazz,methods_MainActivity, sizeof(methods_MainActivity)/ sizeof(methods_MainActivity[0])); } jint RegisterNatives2(JNIEnv *env){ jclass clazz = env->FindClass("com/example/jnidemo/MainActivity"); if(clazz == NULL){ return JNI_ERR; } JNINativeMethod methods_JNITest[] = { {"stringFromJNI", "()Ljava/lang/String;",(void *) stringFromJNI} }; return env->RegisterNatives(clazz,methods_JNITest, sizeof(methods_JNITest)/ sizeof(methods_JNITest[0])); } jint JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env = NULL; if(vm->GetEnv((void **)&env,JNI_VERSION_1_6)!=JNI_OK){ return JNI_ERR; } jint result = RegisterNatives(env); jint result2 = RegisterNatives2(env); return JNI_VERSION_1_6; } //JNIEXPORT jstring JNICALL Java_com_example_jnidemo_MainActivity_stringFromJNI // (JNIEnv *env, jobject obj) { // std::string test = "cmake ++++"; // return env->NewStringUTF(test.c_str()); //} //JNIEXPORT jstring JNICALL Java_com_example_jnidemo_JNITest_gun // (JNIEnv *env, jobject obj) { // std::string test = "gun ++++"; // return env->NewStringUTF(test.c_str()); //} }4.新建jni接口文件JNITest.kt(这里我的目录与MainActivity同目录,其实无所谓的,配对好哪都行)
package com.example.jnidemo class JNITest{ init { System.loadLibrary("native-lib") } external fun gun(): String companion object{ } }5.MainActivity测试
package com.example.jnidemo import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { init { System.loadLibrary("native-lib") } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) jniText.setText(stringFromJNI()) } external fun stringFromJNI(): String }6.配置bulid.gradle
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 buildToolsVersion "29.0.3" defaultConfig { applicationId "com.example.jnidemo" minSdkVersion 16 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" //cmake添加 externalNativeBuild { cmake { cppFlags "" } } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } //cmake添加 externalNativeBuild { cmake { path "src/main/java/jni/CMakeLists.txt" version "3.10.2" } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.core:core-ktx:1.3.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.1' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }7.如果出现not find EOCD啥的问题,重新Rebuild project就行了。 这里如果在伴生对象里声明接口方法,实现类似java的静态方法,不行,后面在看看吧。