Kotlin使用Jni(Kni啦,哈哈)

    科技2022-08-14  85

    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的静态方法,不行,后面在看看吧。

    Processed: 0.021, SQL: 8