我们就不墨迹了,直接开始,往往我们需要jni给我们回调一些数据,并且是实时的回调,这里我们就需要多写一些东西了
1.先在安卓里面设置好接口以及回调,我自己给你们看源代码
- package com.example.myndkapplication
-
- import android.os.Bundle
- import android.util.Log
- import android.widget.Button
- import androidx.appcompat.app.AppCompatActivity
- import kotlinx.android.synthetic.main.activity_main.*
-
- class MainActivity : AppCompatActivity() {
-
-
- // java回调接口 INativeListener.java
- interface INativeListener {
- fun onCall(str:String)
- }
-
- external fun nativeCallBack(callBack: INativeListener?)
-
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- Log.e("TAG","nativeCallBack================onCreate")
-
- nativeCallBack(object : INativeListener {
- override fun onCall(str: String) {
- Log.e("TAG","nativeCallBack================onCall()====$str")
- runOnUiThread { sample_text.text = str }
- }
- })
-
-
- stringFromJNI()
-
- }
-
-
- external fun stringFromJNI()
-
- companion object {
- // Used to load the 'native-lib' library on application startup.
- init {
- System.loadLibrary("test")
- }
- }
- }
2.我们再来修改jni里面的test.c
这里我们新增了一个线程pthread,一个Java_com_example_myndkapplication_MainActivity_nativeCallBack方法,以及JNI_OnLoad虚拟机环境方法
JNI_OnLoad这个方法不需要任何调用,在jni跑起来以后会自动运行
Android JNI 规定,在非主线程中调用 JNI 函数时需要先通过
AttachCurrentThread方法将当前线程附加到 Java 虚拟机上,以确保 JNI 调用的上下文正确。
- #include <jni.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <unistd.h>
- #include <sys/time.h>
- #include <android/log.h>
- #define TAG "TAG" // 指定您的日志标签
-
- //##########################################################新增内容######################################################
-
- #include <pthread.h> // 包含线程相关的头文件
-
- // 全局变量,用于存储 Java 虚拟机环境
- JavaVM *g_jvm = NULL;
- jobject global_callback = NULL;
- jmethodID gCallBackMid;
- JNIEnv *env;
-
- void *thread_function(void *arg) {
- // 将当前线程附加到Java虚拟机上,获取JNIEnv指针
- if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
- // 获取JNIEnv失败
- return NULL;
- }
-
- while (true) {
- // 在这里执行你的应用逻辑,生成新的 ch 数据
- jstring jstr = (*env)->NewStringUTF(env, "write success");
-
- // 回调到java层
- (*env)->CallVoidMethod(env, global_callback, gCallBackMid, jstr);
-
- // 释放本地引用
- (*env)->DeleteLocalRef(env, jstr);
-
- // 等待一段时间,比如 1 秒
- sleep(1); // 单位是秒
- }
-
- // 将当前线程从Java虚拟机上分离
- (*g_jvm)->DetachCurrentThread(g_jvm);
- return NULL;
- }
-
- // JNI 初始化函数,保存 Java 虚拟机环境
- JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
- g_jvm = vm; // 保存 Java 虚拟机环境到全局变量 g_jvm
- return JNI_VERSION_1_6;
- }
-
- // JNI 回调函数,保存回调对象
- JNIEXPORT void JNICALL
- Java_com_example_myndkapplication_MainActivity_nativeCallBack(JNIEnv *env, jobject thiz, jobject call_back) {
- // 创建一个 JNI 全局引用
- global_callback = (*env)->NewGlobalRef(env, call_back);
-
- // 获取回调方法的方法ID
- jclass cls = (*env)->GetObjectClass(env, call_back);
- gCallBackMid = (*env)->GetMethodID(env, cls, "onCall", "(Ljava/lang/String;)V");
- __android_log_print(ANDROID_LOG_DEBUG, TAG, "Java_com_example_myndkapplication_MainActivity_nativeCallBack\n");
- // 创建新线程并启动
- pthread_t thread;
- pthread_create(&thread, NULL, thread_function, NULL);
- }
-
-
- //######################################################################################################################################
-
-
- JNIEXPORT jstring JNICALL
- Java_com_example_myndkapplication_MainActivity_stringFromJNI(JNIEnv *env, jobject obj) {
-
-
- __android_log_print(ANDROID_LOG_DEBUG, TAG, "test_begain\r\n: %s", "===========stringFromJNI=======1======");
-
-
- //pthread_t thread;
- //pthread_create(&thread, NULL, start_app, NULL);
-
- __android_log_print(ANDROID_LOG_DEBUG, TAG, "test_end\r\n: %s", "===========stringFromJNI=======2======");
-
- return (*env)->NewStringUTF(env, "===========stringFromJNI=======3======");
- }
3.运行并生成so库供apk使用

然后就可以看到jni在一直发送消息给安卓界面
