🔥 Android Studio 版本 🔥
🔥 创建包含JNI相关函数类 JNIInvokeMethod.java 🔥
package com.cmake.ndk1.jni; import com.cmake.ndk1.base.ICallbackMethod; import com.cmake.ndk1.base.IThreadCallback; public class JNIInvokeMethod { static { System.loadLibrary("invoke-method-lib"); } public native void nativeCallback(ICallbackMethod callback); public native void nativeThreadCallback(IThreadCallback callback); }
🔥 配置动态库名称 🔥
add_library( #动态库名称 invoke-method-lib invoke-method-lib SHARED jni/jni_invoke_method.cpp )
🔥 生成可关联的库链接 🔥
为了让Java能够调用 invoke-method-lib 库中的函数,您需要使用 CMake 构建脚本中的 target_link_libraries() 命令来关联 invoke-method-lib 库文章来源:https://www.toymoban.com/news/detail-568038.html
target_link_libraries( # Specifies the target library. ndk1 person-lib dynamic-lib basic-type-lib string-lib reference-type-lib access-field-lib access-method-lib invoke-method-lib # Links the target library to the log library # included in the NDK. ) )
🔥 提供给Native调用的日志库链接 🔥
target_link_libraries( # Specifies the target library. invoke-method-lib # Links the target library to the log library # included in the NDK. ${log-lib})
🔥 Native层实现 JNIInvokeMethod 类下面的JNI接口 🔥
#include <jni.h> #include <base.h> #include <pthread.h> void *threadCallback(void *); //全局变量 static jclass threadClazz; static jmethodID threadMethod; static jobject threadObject; // Native中传一个接口和传一个类是一样的传法 extern "C" JNIEXPORT void JNICALL Java_com_cmake_ndk1_jni_JNIInvokeMethod_nativeCallback(JNIEnv *env, jobject instance, jobject callback) { LOGD("nativeCallback"); //获取 Object 赋值给 jclass jclass callbackClazz = env->GetObjectClass(callback); //通过 jclass 获取 methodID jmethodID callbackMethod = env->GetMethodID(callbackClazz, "callBack", "()V"); // 通过 methodID 调用 callbackMethod env->CallVoidMethod(callback, callbackMethod); } /* * 声明 JavaVM 指针 * 如何获取JavaVM? * 1.在JNI_OnLoad函数中获取 * 2.(*env)->GetJavaVM(env,&javaVM); */ JavaVM *gVM; extern "C" JNIEXPORT void JNICALL Java_com_cmake_ndk1_jni_JNIInvokeMethod_nativeThreadCallback(JNIEnv *env, jobject thiz, jobject callback) { //NewGlobalRef 全局引用 threadObject = env->NewGlobalRef(callback); threadClazz = env->GetObjectClass(callback); threadMethod=env->GetMethodID(threadClazz,"callback","()V"); pthread_t handle; //线程创建 pthread_create(&handle, nullptr, threadCallback, nullptr); } //我们之前回调Java函数都需要一个env的方法 //这里却没有,因为env是不跨线程的 //在加载so库的时候有一个JVM //在jni_dynamic_load.cpp 文件里面有一个JNI_OnLoad 函数 //当调用JNI_OnLoad函数时候保存JVM的变量作为全局变量,下次通过JVM获取env void *threadCallback(void *) { //获取Java的jvm实例 //JavaVM *gVM = getJvm(); //实现在子线程中拿到env JNIEnv *env = nullptr; // 返回成功是0 if (gVM->AttachCurrentThread(&env, nullptr) == 0) { //实现回调Java方法 env->CallVoidMethod(threadObject, threadMethod); //DetachCurrentThread()和AttachCurrentThread()配套使用 gVM->DetachCurrentThread(); } return 0; } JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm,void *reserved){ gVM = vm; LOGD("jni onLoad call"); return JNI_VERSION_1_6; }
🔥 运行结果 🔥
package com.cmake.ndk1; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import com.cmake.ndk1.base.ICallbackMethod; import com.cmake.ndk1.base.IThreadCallback; import com.cmake.ndk1.jni.JNIAccessMethod; import com.cmake.ndk1.jni.JNIInvokeMethod; import com.cmake.ndk1.model.Animal; public class MainActivity8 extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final JNIInvokeMethod jniInvokeMethod = new JNIInvokeMethod(); final TextView textView = findViewById(R.id.sample_text); textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { jniInvokeMethod.nativeCallback(new ICallbackMethod() { @Override public void callBack() { Log.i("MainActivity8", "thread name is" + Thread.currentThread().getName()); } }); jniInvokeMethod.nativeThreadCallback(new IThreadCallback() { @Override public void callback() { Log.i("MainActivity8", "thread name is" + Thread.currentThread().getName()); } }); } }); } }
D/LOG_JNI: nativeCallback I/MainActivity8: thread name ismain I/MainActivity8: thread name isThread-3
下载案例文章来源地址https://www.toymoban.com/news/detail-568038.html
到了这里,关于Android Java代码与JNI交互 JNI子线程访问Java方法 (八)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!