• linux+ndk把jni制作成so库供apk使用(带线程的回调)


    我们就不墨迹了,直接开始,往往我们需要jni给我们回调一些数据,并且是实时的回调,这里我们就需要多写一些东西了

    1.先在安卓里面设置好接口以及回调,我自己给你们看源代码

    1. package com.example.myndkapplication
    2. import android.os.Bundle
    3. import android.util.Log
    4. import android.widget.Button
    5. import androidx.appcompat.app.AppCompatActivity
    6. import kotlinx.android.synthetic.main.activity_main.*
    7. class MainActivity : AppCompatActivity() {
    8. // java回调接口 INativeListener.java
    9. interface INativeListener {
    10. fun onCall(str:String)
    11. }
    12. external fun nativeCallBack(callBack: INativeListener?)
    13. override fun onCreate(savedInstanceState: Bundle?) {
    14. super.onCreate(savedInstanceState)
    15. setContentView(R.layout.activity_main)
    16. Log.e("TAG","nativeCallBack================onCreate")
    17. nativeCallBack(object : INativeListener {
    18. override fun onCall(str: String) {
    19. Log.e("TAG","nativeCallBack================onCall()====$str")
    20. runOnUiThread { sample_text.text = str }
    21. }
    22. })
    23. stringFromJNI()
    24. }
    25. external fun stringFromJNI()
    26. companion object {
    27. // Used to load the 'native-lib' library on application startup.
    28. init {
    29. System.loadLibrary("test")
    30. }
    31. }
    32. }

    2.我们再来修改jni里面的test.c 

    这里我们新增了一个线程pthread,一个Java_com_example_myndkapplication_MainActivity_nativeCallBack方法,以及JNI_OnLoad虚拟机环境方法

    JNI_OnLoad这个方法不需要任何调用,在jni跑起来以后会自动运行

    Android JNI 规定,在非主线程中调用 JNI 函数时需要先通过 AttachCurrentThread 方法将当前线程附加到 Java 虚拟机上,以确保 JNI 调用的上下文正确。

    1. #include <jni.h>
    2. #include <stdio.h>
    3. #include <string.h>
    4. #include <stdlib.h>
    5. #include <stdbool.h>
    6. #include <unistd.h>
    7. #include <sys/time.h>
    8. #include <android/log.h>
    9. #define TAG "TAG" // 指定您的日志标签
    10. //##########################################################新增内容######################################################
    11. #include <pthread.h> // 包含线程相关的头文件
    12. // 全局变量,用于存储 Java 虚拟机环境
    13. JavaVM *g_jvm = NULL;
    14. jobject global_callback = NULL;
    15. jmethodID gCallBackMid;
    16. JNIEnv *env;
    17. void *thread_function(void *arg) {
    18. // 将当前线程附加到Java虚拟机上,获取JNIEnv指针
    19. if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) {
    20. // 获取JNIEnv失败
    21. return NULL;
    22. }
    23. while (true) {
    24. // 在这里执行你的应用逻辑,生成新的 ch 数据
    25. jstring jstr = (*env)->NewStringUTF(env, "write success");
    26. // 回调到java层
    27. (*env)->CallVoidMethod(env, global_callback, gCallBackMid, jstr);
    28. // 释放本地引用
    29. (*env)->DeleteLocalRef(env, jstr);
    30. // 等待一段时间,比如 1
    31. sleep(1); // 单位是秒
    32. }
    33. // 将当前线程从Java虚拟机上分离
    34. (*g_jvm)->DetachCurrentThread(g_jvm);
    35. return NULL;
    36. }
    37. // JNI 初始化函数,保存 Java 虚拟机环境
    38. JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    39. g_jvm = vm; // 保存 Java 虚拟机环境到全局变量 g_jvm
    40. return JNI_VERSION_1_6;
    41. }
    42. // JNI 回调函数,保存回调对象
    43. JNIEXPORT void JNICALL
    44. Java_com_example_myndkapplication_MainActivity_nativeCallBack(JNIEnv *env, jobject thiz, jobject call_back) {
    45. // 创建一个 JNI 全局引用
    46. global_callback = (*env)->NewGlobalRef(env, call_back);
    47. // 获取回调方法的方法ID
    48. jclass cls = (*env)->GetObjectClass(env, call_back);
    49. gCallBackMid = (*env)->GetMethodID(env, cls, "onCall", "(Ljava/lang/String;)V");
    50. __android_log_print(ANDROID_LOG_DEBUG, TAG, "Java_com_example_myndkapplication_MainActivity_nativeCallBack\n");
    51. // 创建新线程并启动
    52. pthread_t thread;
    53. pthread_create(&thread, NULL, thread_function, NULL);
    54. }
    55. //######################################################################################################################################
    56. JNIEXPORT jstring JNICALL
    57. Java_com_example_myndkapplication_MainActivity_stringFromJNI(JNIEnv *env, jobject obj) {
    58. __android_log_print(ANDROID_LOG_DEBUG, TAG, "test_begain\r\n: %s", "===========stringFromJNI=======1======");
    59. //pthread_t thread;
    60. //pthread_create(&thread, NULL, start_app, NULL);
    61. __android_log_print(ANDROID_LOG_DEBUG, TAG, "test_end\r\n: %s", "===========stringFromJNI=======2======");
    62. return (*env)->NewStringUTF(env, "===========stringFromJNI=======3======");
    63. }

    3.运行并生成so库供apk使用 

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

  • 相关阅读:
    Android字体大小dp,sp,px系统设置字体大小变化表现
    【代码仓库提交大文件,用Git LFS!】
    Flink DataStream API 编程模型
    【听课笔记】复旦大学遗传学_01孟德尔遗传
    devops自动化运维平台的核心原则有哪些?
    Python 打印素数
    IP协议总结
    java计算机毕业设计ssm+jsp抑郁症科普交流网站
    Vue2源码学习笔记 - 13.响应式原理—Watcher 类详解
    浅谈百思捷国产MES(MOM)产品感悟
  • 原文地址:https://blog.csdn.net/qq_36333309/article/details/138188748