Android JNI实现锅炉压力显示系统详解

news2024/11/24 9:15:13

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂,风趣幽默",感觉非常有意思,忍不住分享一下给大家。
👉点击跳转到教程

第一步创建GuoLu.c文件

//
// Created by DELL on 2023/8/13.
//
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <unistd.h>

int pressure = 20;

int getPressure() {
    int increase = rand() % 25;
    pressure += increase;
    return pressure;
}

/**
 * 从锅炉感应器中得到锅炉压力值
 */
jint Java_com_example_guolu_MainActivity_getPressure(JNIEnv *env, jobject thiz) {
    int pressure = getPressure();
    return pressure;
}

第二步在build.gradle文件中,进行相关配置

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 33
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.example.guolu"
        minSdkVersion 23
        targetSdkVersion 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        // 增加cmake控制属性
        externalNativeBuild {
            cmake {
                // 指定编译架构
                abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
            }
        }
    }

    // 在android节点下
    // 指定CMakeLists.txt路径
    externalNativeBuild {
        cmake {
            // 在该文件种设置所要编写的c源码位置,以及编译后so文件的名字
            path 'CMakeLists.txt'
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

第三步实现在MainActivity中,调用相关的C代码,显示锅炉压力值,根据压力值显示不同的UI在Android设备上

public class MainActivity extends AppCompatActivity {
    {
        System.loadLibrary("GuoLu");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PressureView pressureView = new PressureView(this);
        setContentView(pressureView);
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    SystemClock.sleep(1000);
                    int pressure = Math.round(getPressure());//0-250
                    pressureView.setPressure(pressure);
                    if (pressure > 220) {//如果压力大于220就要爆炸
                        break;
                    }
                }
            }
        }).start();
    }

    /**
     * native代码
     * 调用C代码中对应的方法
     *
     * @return
     */
    public native int getPressure();
}

第四步实现自定义View,PressureView

/**
 * @Author: ly
 * @Date: 2023/8/13
 * @Description: 锅炉压力值显示自定义view
 */
public class PressureView extends View {
    /**
     * 锅炉压力值
     */
    private int pressure;
    /**
     * 画笔
     */
    private Paint paint;

    public PressureView(Context context) {
        this(context, null);
    }

    public PressureView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PressureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);//设置抗锯齿
        paint.setTextSize(20);
    }

    public void setPressure(int pressure) {
        this.pressure = pressure;
//        invalidate(); 在主线程调用
        postInvalidate();//在子线程使用这个进行绘制 onDraw() 执行
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (pressure > 220) {
            //1.如果压力值大于200,就绘制文本,显示锅炉爆炸了,快跑
            canvas.drawText("快跑!", 10, getHeight() / 2, paint);
        } else {
            //2.正常和提示的情况
            paint.setColor(Color.GRAY);
            canvas.drawRect(10, 10, 60, 260, paint);
            //设置背景颜色为灰色
            //2.1.如果小于200正常显示,并且设置画笔颜色,绿色
            if (pressure < 200) {
                paint.setColor(Color.GREEN);
                canvas.drawRect(10, 260 - pressure, 60, 260, paint);
            }
            //2.2.如果大于200警示显示,并且设置画笔颜色,红色
            if (pressure > 200) {
                paint.setColor(Color.RED);
                canvas.drawRect(10, 260 - pressure, 60, 260, paint);
            }
        }
    }
}

效果如图所示:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 潮流周刊#15:如何分析 FastAPI 异步请求的性能?

你好&#xff0c;我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容&#xff0c;大部分为英文。标题取自其中一则分享&#xff0c;不代表全部内容都是该主题&#xff0c;特此声明。 本周刊精心筛选国内外的 250 信息源&#xff0c;为你挑选最值得分享的文章、教程、开源…

记录一下关于word存放代码出现的问题

如下图所示&#xff0c;从 Word 中复制代码并粘贴到其他地方&#xff0c;例如文本编辑器或代码编辑器中&#xff0c;有时会出现额外的连字符或破折号。这是因为 Word 使用了特定的字符编码和格式&#xff0c;而这些字符在代码中可能不被支持或解析为特殊字符。   可见有时从…

Java线程调度以及算法

线程调度概况 Java的线程调度程序是JVM的一部分&#xff0c;它决定应该运行哪个线程。无法保证线程调度程序将选择运行哪个可运行线程。 一次只能有一个线程在一个进程中运行。线程调度程序主要使用抢占式或时间切片调度来调度线程。 抢占式调度与时间分片的区别 在抢占式调…

边缘计算:下一代计算模式的突破

章节一&#xff1a;引言 随着物联网、人工智能和大数据等技术的不断发展&#xff0c;计算需求变得越来越复杂&#xff0c;传统的云计算模式已经难以满足快速增长的数据处理需求。在这样的背景下&#xff0c;边缘计算作为一种全新的计算模式崭露头角&#xff0c;为我们带来了更加…

Pytorch深度学习-----实现神经网络模型在GPU上进行训练的方法

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

css3新增选择器总结

目录 一、属性选择器 二、结构伪类选择器 三、伪元素选择器 四、UI状态伪类选择器 五、反选伪类选择器 六、target选择器 七、父亲选择器、后代选择器 八、相邻兄弟选择器、兄弟们选择器 一、属性选择器 &#xff08;除IE6外的大部分浏览器支持&#xff09; E&#…

数据库设计,理解第二范式和第三范式的区别

在学习数据库范式的时候&#xff0c;很多人搞不清第二范式和第三范式他到底是有啥区别。 想讲清楚第二范式与第三范式的区别&#xff0c;不得不聊到键和相关属性的概念 键和相关属性的概念 范式的定义会使用到主健和候选健&#xff0c;数据库中的健&#xff08;Key)由一个或…

STM32F103C8T6开发笔记1:有线陀螺仪二自由度机械臂

经过之前几天的快速学习&#xff0c;今日尝试组装一款基于MPU6050陀螺仪控制的二自由度机械臂&#xff0c;本文对其使用器材以及基本原理进行介绍~ 组装效果图&#xff1a; 主要元器件如下&#xff1a; 器件个数15 KG以上 舵机3适合舵机的金属夹爪118650电池电源12V1云台支架2…

工博士与纷享销客达成战略合作,开启人工智能领域合作新篇章

近日&#xff0c;工博士与纷享销客在上海正式签署了战略合作协议&#xff0c;正式拉开了双方在人工智能与数字营销领域的合作序幕。这次合作将为双方带来更多机遇和发展空间&#xff0c;并为全球人工智能领域的客户提供更高效、智能的CRM解决方案。 < 双方项目人员合影 >…

React如何配置env环境变量

React版本&#xff1a; "react": "^18.2.0" 1、在package.json平级目录下创建.env文件 2、在‘.env’文件里配置环境变量 【1】PUBLIC_URL 描述&#xff1a;编译时文件的base-href 官方描述&#xff1a; // We use PUBLIC_URL environment variable …

③ vue组件

vue组件创建 在App.vue中添加。 技巧&#xff1a;先import&#xff0c;把vue组件地址写出来。然后在template中写名字。剩下的就自动生成。要看下import有没有多生成什么。 注意1&#xff1a; 注意2&#xff1a; 不只是能在App.vue中引入组件。任意组件中都可以引用其他组件…

msvcp110.dll丢失怎样修复,msvcp110.dll丢失修复方法

msvcp110.dll是Microsoft C库的一部分&#xff0c;它是运行依赖于该库的程序所必需的动态链接库文件。它的作用是提供C运行时库函数的实现&#xff0c;这些函数用于处理程序的内存管理、异常处理、多线程支持等。当系统中缺少或损坏了msvcp110.dll文件时&#xff0c;请及时修复…

STM32--TIM定时器(1)

文章目录 TIM简介定时器类型 通用定时器预分频器时序计数器时序定时中断基本结构TIM内部中断工程TIM外部中断工程 TIM简介 STM32的TIM&#xff08;定时器&#xff09;是一种非常常用的外设&#xff0c;用于实现各种定时和计数功能。它是基于时钟信号进行计数&#xff0c;并在计…

Redis的单线程与多线程

Redis的核心处理逻辑一直都是单线程 有一些分支模块是多线程(某些异步流程从4.0开始用的多线程&#xff0c;例如UNLINK、FLUSHALL ASYNC、FLUSHDB ASYNC等非阻塞的删除操作。网络I/O解包从6.0开始用的是多线程;) 为什么是单线程 多线程多好啊可以利用多核优势 官方给的解释 …

二、编写第一个 Spring MVC 程序

文章目录 一、编写第一个 Spring MVC 程序 一、编写第一个 Spring MVC 程序 代码示例 创建 maven 项目&#xff0c;以此项目为父项目&#xff0c;在父项目的 pom.xml 中导入相关依赖 <dependencies><dependency><groupId>junit</groupId><artifactI…

阿里云ACP知识点

前言&#xff1a;记录ACP错题 1、在创建阿里云ECS时&#xff0c;每台服务器必须要包含_______用来存储操作系统和核心配置。 系统盘&#xff08;不是实例&#xff0c;实例是一个虚拟的计算环境&#xff0c;由CPU、内存、系统盘和运行的操作系统组成&#xff1b;ESC实例作为云…

web基础和tomcat的安装,部署jpress应用

目录 1. 简述静态网页和动态网页的区别。 2. 简述 Webl.0 和 Web2.0 的区别。 3. 安装tomcat8&#xff0c;配置服务启动脚本&#xff0c;部署jpress应用。 1. 简述静态网页和动态网页的区别。 【1】定义区别 请求响应信息&#xff0c;发给客户端进行处理&#xff0c;由浏览…

81. 搜索旋转排序数组 II

题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 解题思路&#xff1a; 解法一&#xff1a;直接从前往后搜索&#xff0c;时间复杂度O(n) AC代码&#xff1a; class Solution {public boolean search(int[] nums, int target)…

在收藏夹里“积灰”的好东西——“收藏从未停止,行动从未开始”

方向一&#xff1a;分享一道你收藏的好题 小雅兰刚学数据结构与算法的时候&#xff0c;学的真的是很吃力&#xff0c;感觉链表真的特别的难&#xff0c;在学习了后面的知识之后&#xff0c;发现链表慢慢变得简单了&#xff0c;若是放在现在&#xff0c;小雅兰仍然觉得链表的知…

JProfiler —CPU评测

当JProfiler测量方法调用的执行时间及其调用堆栈时&#xff0c;我们称之为“CPU评测”。这些数据以多种方式呈现。根据你试图解决的问题&#xff0c;其中一个或另一个演示将是最有帮助的。默认情况下不会记录CPU数据&#xff0c;您必须打开CPU记录才能捕获有趣的用例。 一、调…