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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/575128.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Python实现心脏病数据可视化DEA+预测【500010103.1】

一、数据说明 该心脏病数据集是通过组合 5 个已经独立可用但以前未合并的流行心脏病数据集来策划的。在这个数据集中&#xff0c;5 个心脏数据集结合了 11 个共同特征&#xff0c;使其成为迄今为止可用于研究目的的最大心脏病数据集。 该数据集由 1190 个实例和 11 个特征组成…

wstunnel (websocket模式ssh)

接上一篇 修改客户端运行参数 ssh -o ProxyCommand"./wstunnel client -L stdio://%h:%p ws://192.168.254.131:8080" 127.0.0.1 其中127.0.0.1为服务端的本地ssh访问&#xff0c;可以修改为通过服务端访问其他设备的ssh服务。例如&#xff1a; ssh -o ProxyComma…

线性代数-行列式-p1 矩阵的秩

目录 1.定义 2. 计算矩阵的秩 3. 矩阵的秩性质 1.定义 2. 计算矩阵的秩 3. 矩阵的秩性质

JavaEE——spring MVC请求处理

目录 主要目的&#xff1a; 1. Spring web 项目搭建 2. 添加依赖 3. 配置插件 4. 配置设置类 5. 编写controller层类 6. 编写测试的http请求 主要目的&#xff1a; 创建一个spring web项目&#xff1b; 创建控制类&#xff1b; 掌握如何配置MVC&#xff1b; 编写htt…

HTTP 网络协议的请求头信息,响应头信息,具体详解(2024-04-26)

1、通用头部 2、常见的 HTTP请求头信息 HTTP 响应头信息是服务器在响应客户端的HTTP请求时发送的一系列头字段&#xff0c;它们提供了关于响应的附加信息和服务器的指令。 3、常见的 HTTP 响应头信息 响应头向客户端提供一些额外信息&#xff0c;比如谁在发送响应、响应者的功…

AI预测福彩3D第9套算法实战化测试第3弹2024年4月25日第3次测试

今天继续进行新算法的测试&#xff0c;今天是第3次测试。好了&#xff0c;废话不多说了&#xff0c;直接上图上结果。 2024年4月25日福彩3D预测结果 6码定位方案如下&#xff1a; 百位&#xff1a;6、4、3、7、2、8 十位&#xff1a;8、4、9、3、1、0 个位&#xff1a;7、6、9、…

审稿快、出版效率高的8本检验医学中文期刊推荐!

常笑医学整理了8本比较好投的检验医学中文期刊&#xff0c;以及期刊详细参数&#xff0c;供大家在论文投稿时参考。这些检验医学期刊&#xff0c;审稿快、出版效率高&#xff0c;有需要的赶紧收藏&#xff01; 1.《中华检验医学杂志》 &#xff08;详细投稿信息请点击刊物名称…

【网站项目】考研助手

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

uniapp-css:拼图(不规则图片拼插)、碎片

拼图案例样式 高斯模糊的地方可以对应的使用fliter属性和opacity来调节样式。 其余碎片和图片对应: 这段代码实现了一个拼图效果的Vue组件。以下是对代码的详细解析: 模板部分: 在模板中使用v-for指令遍历imgs数组中的每个图片对象,为每个图片创建一个元素。 使用:cla…

Day 31 贪心算法理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和

贪心算法理论基础 ​ 贪心算法的本质&#xff1a;选择每一个阶段的局部最优&#xff0c;从而达到系统的整体最优&#xff1b; ​ 贪心的套路就是没有套路&#xff0c;最好的策略就是举反例&#xff0c;因为大多数时候并不要求严格证明&#xff0c;只需要得到普遍性结论即可&a…

优化大模型的解释性提示以提升文本推理性能:一种无监督数据驱动的方法

介绍一篇大模型前沿论文&#xff0c;《Explanation Selection Using Unlabeled Data for Chain-of-Thought Prompting》。在这篇论文中&#xff0c;作者Xi Ye和Greg Durrett探讨了如何通过优化大语言模型&#xff08;LLMs&#xff09;的解释性提示来提升文本推理任务的性能。他…

CSS 标准流 浮动 Flex布局

目录 1. 标准流2. 浮动2.1 清除浮动 3. Flex 布局3.1 Flex 组成3.2 Flex 布局 - 主轴与侧轴对齐方式3.2.1 主轴对齐方式3.2.2 侧轴对齐方式 3.3 Flex 布局 - 修改主轴方向3.4 Flex 布局 - 弹性伸缩比3.5 Flex 布局 - 弹性盒子换行3.6 Flex 布局 - 行对齐方式 1. 标准流 标准流…

OU和域用户的创建

OU和域用户的创建 导航 文章目录 OU和域用户的创建导航一、创建ou二、创建用户三、验证 一、创建ou 在服务器管理器里面点击右上角的工具,选择Active Directory 用户和计算机右击我们的域,选择新建,选择组织单位,并填入我们的单位名字 二、创建用户 右击我们刚刚新建的组织…

Linux(Centos)服务器探索ffmpeg笔记 (命令行、Nvidia硬件加速、GPU、CPU、CUDA、h264_nvenc、过滤器、加水印)

目录 前言内容简介为什么会有这篇文章 1、服务器上怎么使用ffmpeg1.1 使用编译好的&#xff08;需要root权限&#xff09;1.2 自己怎么编译&#xff08;需要root权限&#xff09; 2 、非Root用户要怎么安装和使用3、ffmpeg命令的一些使用引导和参数介绍3.1 编译参数3.2 查询支持…

解读六西格玛培训:企业为何不能忽视其重要性?

六西格玛培训&#xff0c;听起来可能是一个陌生的名词&#xff0c;但当深入探索其内涵后&#xff0c;会发现它实际上是企业追求卓越的必由之路。 想象一下&#xff0c;你正在驾驶一辆赛车&#xff0c;在赛道上追求极致的速度与精准。然而&#xff0c;每一个微小的失误都可能导致…

window平台C#实现软件升级功能(控制台)

window平台C#实现软件升级功能 之前用window窗体实现过一个升级功能&#xff0c;后来发现多个项目都需要升级功能&#xff0c;现改成可接收参数实现一种通用的exe.改用控制台方式实现这个升级功能&#xff0c;这样不仅实现了接收参数&#xff0c;升级程序体积也比原来的窗体形式…

如何让Ubuntu上的MySQL开发更便捷

前言 作为一款开源的数据库开发与数据库管理协同工具&#xff0c;&#xff08;OceanBase Developer Center&#xff0c;简称ODC&#xff09;&#xff0c;针对MySQL数据源&#xff0c;已提供了涵盖SQL开发、变更风险管控、数据安全合规等多个方面的功能&#xff0c;从而为MySQL…

Java集合框架-Collection-List-vector(遗留类)

目录 一、vector层次结构图二、概述三、底层数据结构四、常用方法五、和ArrayList的对比 一、vector层次结构图 二、概述 Vector类是单列集合List接口的一个实现类。与ArrayList类似&#xff0c;Vector也实现了一个可以动态修改的数组&#xff0c;两者最本质的区别在于——Vec…

# 使用 Hystrix 的线程池,idea 报错显示 HystrixThreadPoo1Properties.Setter 报红。

使用 Hystrix 的线程池&#xff0c;idea 报错显示 HystrixThreadPoo1Properties.Setter 报红。 一、可能的原因&#xff1a; 1、拼写错误&#xff1a; HystrixThreadPoo1Properties.Setter 中的 “Poo1” 可能是拼写错误&#xff0c;应为“Pool”。 2、类或方法不存在&#…

BGP配置和应用案例

策略路由的配置步骤 l 策略路由的配置步骤如下&#xff1a; 创建route-map 通过ACL匹配感兴趣的数据&#xff0c;定义策略动作 在指定接口下通过ip policy 命令应用route-map l 最终实现对通过该接口进入设备的数据进行检查&#xff0c;对匹配的数据执行规定的策略…
最新文章