我们就不墨迹了,直接开始,往往我们需要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在一直发送消息给安卓界面