第一步创建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); } } } }
效果如图所示: