Android使用Jni实现压力锅数据检测效果示例

本文实例讲述了Android使用Jni实现压力锅数据检测效果。分享给大家供大家参考,具体如下:

1、创建主页:

package com.android.imooc.jni;
import com.android.imooc.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
/**
 * @描述     模仿压力锅检测数据
 * @项目名称   App_imooc
 * @包名     com.android.imooc.jni
 * @类名     MonitorActivity
 * @author   chenlin
 * @date    2012年6月9日 下午3:18:11
 * @version   1.0
 */
public class MonitorActivity extends Activity {
  static{
    System.loadLibrary("monitor");
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_monitor);
  }
  public void start(View view){
    startMonitor();
  }
  public void stop(View view){
    stopMonitor();
  }
  public native void startMonitor();
  public native void stopMonitor();
}

2、在jni文件夹里写Monitor.c

#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <string.h>
//获得0到100的随机数
int getPressure(){
  return rand() % 101;
}

3、布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  tools:context=".MainActivity" >
  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="start"
    android:text="开始监测" />
  <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="stop"
    android:text="结束监测" />
  <com.android.imooc.jni.MyProgressBar
    android:id="@+id/pb"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

4、进度条代码

package com.android.imooc.jni;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class MyProgressBar extends View {
  //压力
  private int mPresure;
  //最大值
  private int mMax;
  public MyProgressBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }
  public MyProgressBar(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
  public MyProgressBar(Context context) {
    super(context);
  }
  public void setPressure(int pressure) {
    this.mPresure = pressure;
    // invalidate();
    postInvalidate();
  }
  public void setMax(int max) {
    this.mMax = max;
  }
  @Override
  protected void onDraw(Canvas canvas) {
    Paint paint = new Paint();
    if (mPresure < 50) {
      paint.setColor(Color.GREEN);
    } else if (mPresure < 80) {
      paint.setColor(0xffff8800);
    } else {
      paint.setColor(Color.RED);
    }
    canvas.drawRect(10, 10 + mMax - mPresure, 30, 10 + mMax, paint);
  }
}

5、转到项目的src目录,打开cmd窗口
输入:

javah com.android.imooc.jni.MonitorActivity

生成文件com_android_imooc_jni_MonitorActivity
打开,把里面的两个方法
拷贝到Monitor.c里

/*
 * Class:   com_android_imooc_jni_MonitorActivity
 * Method:  startMonitor
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_android_imooc_jni_MonitorActivity_startMonitor
 (JNIEnv *, jobject);
/*
 * Class:   com_android_imooc_jni_MonitorActivity
 * Method:  stopMonitor
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_android_imooc_jni_MonitorActivity_stopMonitor
 (JNIEnv *, jobject);

6、实现上面的两个方法

1)首先在主页面得到进度条

private MyProgressBar mProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_monitor);
  mProgressBar = (MyProgressBar) findViewById(R.id.pb);
  mProgressBar.setMax(100);
}
public void showProgress(int progress){
  mProgressBar.setPressure(progress);
}

2)实现在Monitor.c里的startMonitor方法

JNIEXPORT void JNICALL Java_com_android_imooc_jni_MonitorActivity_startMonitor
(JNIEnv * env , jobject obj){
while(1){
  //得到压力数据
   int progress = getPressure();
   //使用反射的方法调用java里的showProgress方法
   //1、拿到字节吗
   jclass clazz = ( *env)->FindClass(env, "com/android/imooc/jni/MonitorActivity");
   //2、获得方法id,首先要获得函数签名,进入到项目的bin/classes目录-->打开cmd窗口-->输入命令
  // E:\androidproject\App_imooc\bin\classes>javap -s com/android/imooc/jni/MonitorActivity
  //获得签名“(I)V”
    jmethodID id = ( *env)->GetMethodID(env, clazz, "showProgress", "(I)V");
   //3、回调
  ( *env)->CallVoidMethod(env, obj, id, progress);
}
}

3)、因为上面的方法使用了while(1)循环,所以在java页面的方法里必须使用子线程

public void start(View view){
    new Thread(new Runnable() {
      @Override
      public void run() {
        startMonitor();
      }
    }).start();
}

4)如何实现停止呢?

定义变量int monitor;
在方法Java_com_android_imooc_jni_MonitorActivity_startMonitor里初始化为monitor = 1

while(monitor){
…………………
}

在方法Java_com_android_imooc_jni_MonitorActivity_stopMonitor里初始化为monitor = 0

7、最后代码Monitor.c

#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <string.h>
//获得0到100的随机数
int getPressure(){
  return rand() % 101;
}
int monitor;
JNIEXPORT void JNICALL Java_com_android_imooc_jni_MonitorActivity_startMonitor
(JNIEnv * env , jobject obj){
  monitor = 1;
  while(monitor){
    int progress = getPressure();
       //使用反射调用java方法
       //拿到字节吗
      jclass clazz = ( *env)->FindClass(env, "com/android/imooc/jni/MonitorActivity");
      //获得方法id
      //jmethodID  (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
      jmethodID id = ( *env)->GetMethodID(env, clazz, "showProgress", "(I)V");
      //回调
      //void    (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
      ( *env)->CallVoidMethod(env, obj, id, progress);
      sleep(0.3f);
  }
}
JNIEXPORT void JNICALL Java_com_android_imooc_jni_MonitorActivity_stopMonitor
(JNIEnv * env , jobject obj){
  monitor = 0;
}

主页代码:

/**
 * @描述     模仿压力锅检测数据
 * @项目名称   App_imooc
 * @包名     com.android.imooc.jni
 * @类名     MonitorActivity
 * @author   chenlin
 * @date    2012年6月9日 下午3:18:11
 * @version   1.0
 */
public class MonitorActivity extends Activity {
  private MyProgressBar mProgressBar;
  static{
    System.loadLibrary("monitor");
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_monitor);
    mProgressBar = (MyProgressBar) findViewById(R.id.pb);
    mProgressBar.setMax(100);
  }
  public void start(View view){
    new Thread(new Runnable() {
      @Override
      public void run() {
        startMonitor();
      }
    }).start();
  }
  public void stop(View view){
    stopMonitor();
  }
  public native void startMonitor();
  public native void stopMonitor();
  public void showProgress(int progress){
    mProgressBar.setPressure(progress);
  }
}

8、效果如图

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android基本组件用法总结》、《Android开发入门与进阶教程》、《Android布局layout技巧总结》、《Android视图View技巧总结》、《Android编程之activity操作技巧总结》、《Android资源操作技巧汇总》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

(0)

相关推荐

  • 详解Android JNI的基本使用(CMake)

    简介 什么是JNI JNI的全称是Java Native Interface:Java本地开发接口,它提供了若干的API实现了Java和其他语言的通信(主要是C和C++),目的就是Java可以调用C或C++开发的函数,C或C++也能调用Java的方法.这样有很多有点,其一就是效率,C/C++是本地语言,比java更高效:其二就是可以复用已经存在的C/C++代码:其三是Java反编译比C语言容易,一般加密算法都是用C语言编写,不容易被反编译. 什么是NDK和CMake NDK全称是Native D

  • 浅谈Android Studio JNI生成so库

    1.新建Android studio工程 2.新建class:AppKey.java.主要为了保存密钥 代码块 package com...adminapp.lib.utils.jni; /** * Created by seven on 16/9/8. */ public class AppKey { static { System.loadLibrary("AppKey"); } public static native String WechatId(); public stat

  • 详解AndroidStudio JNI +Gradle3.0以上JNI爬坑之旅

    1.首先什么是JNI呢? JNI--(Java Native Interface),他是java平台的特性,不是安卓系统提供的.他定义了一些JNI函数,来让开发者可以通过调用这些函数来实现java代码调用C/C++代码. 2.如何使用JNI呢? 我们先将写好的C/C++代码编译成对应平台的动态库(windows是.dll文件,linux是.so文件). 下面我们来举个栗子:使用AndroidStudio来实现JNI 3.要实现JNI先下载NDK,那么NDK又是什么呢?(面试宝典来了,赶紧掏出小本

  • Android在JNI中使用ByteBuffer的方法

    本文实例讲述了Android在JNI中使用ByteBuffer的方法.分享给大家供大家参考.具体如下: 一.ByteBuffer 定义 在NIO中,数据的读写操作始终是与缓冲区相关联的(读取时信道(SocketChannel)将数据读入缓冲区,写入时首先要将发送的数据按顺序填入缓冲区) 缓冲区是定长的,基本上它只是一个列表,它的所有元素都是基本数据类型.ByteBuffer是最常用的缓冲区,它提供了读写其他数据类型的方法,且信道的读写方法只接收ByteBuffer. ByteBuffer有以下几

  • Android Studio开发之 JNI 篇的简单示例

    前言 Android上层应用使用java开发,不过java并不适合密集型运算,比如图片处理等,遇到密集型运算,一般使用c/c++完成. Java虚拟机支持调用c/c++代码,即JNI(Java Native Interface),它提供了若干的API实现了Java和其他语言的通信.为方便android平台上使用JNI技术,提供了NDK开发包,可以将NDK理解为对JNI的进一步封装,方便开发使用罢了. JNI开发方式有多种,可以在Android 源码中开发,也可以利用其它工具,但都比较烦琐或者要下

  • Android Studio中导入JNI生成的.so库的实现方法

    Android Studio中导入JNI生成的.so库的实现方法 由于在原来的ADT的Eclipse环境中,用ndk_build工具生成了相应的各个.so库文件之后,eclipse工具就会自动把这些库导入到apk中.而Android Studio目前为止(0.86版本)还无法做到那么自动,但是我们可以通过以下方式进行. 首先在Android Studio工程的app目录下创建整个jni目录,jni目录里写Android.mk.Application.mk以及各类C/C++和汇编源文件.然后跟原来

  • Android studio 下JNI编程实例并生成so库的实现代码

    最近需要使用JNI编程,学了下JNI,并且在Android Studio下实现了一个小demo.这期间有一些坑,还好都解决了,想分享出来,希望大家少走弯路.本文中采用的平台是Windows,NDK环境已经搭建好,这方面资料很多,大家可以自行百度. 本文分为两个部分: 1.如何通过编写Jni实现native方法的调用. 2.怎样生成.so动态库提供给第三方使用. 以下是正文: 一,编写jni文件,实现本地方法 1,建立一个新工程,只有一个MainActivity,里面加载库文件并且调用若干本地方法

  • Android通过JNI实现守护进程

    开发一个需要常住后台的App其实是一件非常头疼的事情,不仅要应对国内各大厂商的ROM,还需要应对各类的安全管家...虽然不断的研究各式各样的方法,但是效果并不好,比如任务管理器把App干掉,服务就起不来了... 网上搜寻一番后,主要的方法有以下几种方法,但都是治标不治本: 1.提高Service的优先级:这个,也只能说在系统内存不足需要回收资源的时候,优先级较高,不容易被回收,然并卵... 2.提高Service所在进程的优先级:效果不是很明显 3.在onDestroy方法里重启service:

  • Android jni调试打印char阵列的实例详解

    Android jni调试打印char阵列的实例详解 前言: 在android开发中,用jni有时候需要打印某一个字符串的二进制格式输出,比较友好的输出格式是一个四列,八列,十六列的矩阵格式.类似在错误删除野指针时出现如下错误: pid: 2721, tid: 3005, name: pool-5-thread-5 >>> onxmaps.hunt <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr dea

  • Android JNI c/c++调用java的实例

    Android JNI c/c++调用java的实例 近期通过研究SDL源码 得出Android JNI  c/c++调用Java 无需新建虚拟机,这样省去很多步骤,这样调用Android JNI会变得非常容易,大家看下简单实例: 具体步骤如下 第一步获得:两个参数 JNIEnv和jclass void Java_com_Test_Audio_Init( JNIEnv* env,jclass cls, jobject thiz ) { InitJNI(env,cls); } bool InitJ

  • 记录Android studio JNI开发的三种方式(推荐)

    概述 在Andorid Studio不支持JNI开发之前大家一般都是使用Eclipse开发JNI,各种配置让人觉得很蛋疼.从Andorid Studio支持JNI开发后,让我们开发JNI变的如此简单. NDK 和 JNI介绍 JNI (Java Native Interface)是一套编程接口,用来实现Java代码和其他语言(c.C++或汇编)进行交互.这里需要注意的是JNI是JAVA语言自己的特性,也就是说JNI和Android没有关系.在Windows下面用JAVA做开发也经常会用到JNI,

随机推荐