本帖最后由 cnwutianhao 于 2023-4-20 16:03 编辑
Kotlin 代码:
package com.tyhoo.jni
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.tyhoo.jni.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.sampleText.setOnClickListener {
Log.d(TAG, "nativeMethod")
nativeMethod()
}
}
private external fun nativeMethod()
companion object {
private const val TAG = "Tyhoo"
// Used to load the 'jni' library on application startup.
init {
System.loadLibrary("jni")
}
@JvmStatic
fun staticMethod() {
Log.d(TAG, "staticMethod")
}
}
}
这是 Kotlin 语言编写的 Android 应用程序中的 MainActivity 类,其中声明了一个名为 nativeMethod 的本地方法。该方法会在点击 sampleText 视图时被调用,从而触发 native 方法的执行。在 companion object 中还定义了一个名为 staticMethod 的静态方法,它会在应用程序启动时被加载,用于在 Java 层调用本地方法。这个静态方法可以从 Java 代码中直接调用,而不需要使用 JNI 接口函数。
C++ 代码:
#include <jni.h>
#include <string>
#include <android/log.h>
#define LOG_TAG "Tyhoo"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define CLASSNAME "com/tyhoo/jni/MainActivity"
typedef struct {
JavaVM *vm;
jclass clazz;
} tyhoo_vm;
static tyhoo_vm javaVM;
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *unused) {
JNIEnv *env = nullptr;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
LOGD("JNI_OnLoad GetEnv failed\n");
return -1;
}
jclass clazz = env->FindClass(CLASSNAME);
if (!clazz) {
LOGD("FindClass %s failed\n", CLASSNAME);
return -1;
}
javaVM.vm = vm;
javaVM.clazz = (jclass) env->NewGlobalRef(clazz);
LOGD("JNI_OnLoad, vm: %p, clazz: %p \n", javaVM.vm, javaVM.clazz);
return JNI_VERSION_1_6;
}
void JNI_OnUnload(JavaVM *vm, void *unused) {
JNIEnv *env = nullptr;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
LOGD("JNI_OnLoad GetEnv failed\n");
return;
}
env->DeleteGlobalRef(javaVM.clazz);
}
void callJavaStaticMethod() {
JNIEnv *env = nullptr;
jint res = javaVM.vm->AttachCurrentThread(&env, nullptr);
if (res != JNI_OK) {
return;
}
jclass clazz = javaVM.clazz;
if (clazz == nullptr) {
return;
}
jmethodID method = env->GetStaticMethodID(clazz, "staticMethod", "()V");
env->CallStaticVoidMethod(clazz, method);
}
void *thread_func(void *arg) {
callJavaStaticMethod();
return nullptr;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_tyhoo_jni_MainActivity_nativeMethod(JNIEnv *env, jobject thiz) {
pthread_t thread;
pthread_create(&thread, nullptr, thread_func, nullptr);
}
这是 C++ 语言编写的 JNI 接口函数,用于在 Java 层调用本地方法。这个接口函数的作用是创建新线程,并在新线程中调用 callJavaStaticMethod 方法,这个方法会获取当前线程的 JNIEnv 对象和 Java 类对象,并通过这些对象调用 Java 层的静态方法 staticMethod。
同步发布到我的 GitHub Blog 里:
https://github.com/cnwutianhao/blog/issues/1
|