linux下ADT Bundle实现APP通过jni读取内存信息,以及NDK的使用

来源:互联网 发布:dsc分析软件 编辑:程序博客网 时间:2024/06/06 05:31

关于jni的概念,个人就不多说了,网上随便一搜,各种说法都有,简单提醒一下,一般来说,我们的jni函数都有一个规定:以Java_开头,依次就是包名以及java的类名,后面在跟上函数实现方法名。比如我的java包名为com.example.jni,类名为minardJni,,函数方法名为getString.所以,我在jni里面的函数名就是:Java_com_example_jni_minardJni_getString.下面直接开始干货。

首先,我们先来安装NDK,官网下载网速略慢,我们可以从百度网盘下载(点击直达下载),NDK是编译产生so文件的环境,so文件简单的说就是一个动态链接库,个人以为和C#里的dll文件性质差不多。

下载完的NDK是压缩包,我们可以使用解压命令来解压:tar jxvf xxxxx.tar.bz2,接着我们就配置环境。为了方便使用ndk命令,我们配置全局环境,就是在系统任意目录下都可以使用ndk命令。

1.用vim ~/.bashrc打开并子在文件最末尾新增以下内容:

export NDKHOME="/home/xxxx/androidADT/android-ndk-r9d/"
export PATH=$NDKHOME:$PATH

第一行NDK_HOME添加的就是解压NDK的文件夹的路径,文中是我的路径。

2.使用source ~/.bashrc命令激活修改的环境

3.切换到任意目录下执行ndk-build命令,如果没有提示ndk-build命令存在,就是配置对了,就可以使用ndk了。

注:如果出错,就会在第二步激活的时候报错,根据错误提示去改错,一般来说都是因为NDK的路径写错了,注意环境中的=,前后不可以加空格。


然后,我们就可以开始进行安卓下写jni并进行调用了,请建议参考链接,这个博客我以为写的很详细了,基本上按照博主所说的,能很好的懂jni流程。我在此的基础上说一下,如何读取内存信息。


我们可以在接口的地方在定义一个接口,返回类型为String的,毕竟内存信息都是字符串。如我的:

public native String getString();
在生成的.h头文件里也会多出这么一句代码:

JNIEXPORT jstring JNICALL Java_com_example_jni_minardJni_getString  (JNIEnv *, jobject);

在.c文件里的实现方法为(本次方法实现是读取/proc/meminfo).

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>#include <stdio.h>#include <string.h>#include <android/log.h>//#include "com_example_jni_minardJni.h"const char *path = "/proc/meminfo";/* Header for class com_example_jni_minardJni */#ifndef _Included_com_example_jni_minardJni#define _Included_com_example_jni_minardJni#ifdef __cplusplusextern "C" {#endif/* * Class:     com_example_jni_minardJni * Method:    getString * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_jni_minardJni_getString  (JNIEnv* env, jobject obj){int size;    FILE *fd;    char buffer[1024]={'\0'};    fd = fopen(path,"r");    if(fd < 0)    {        return (*env)->NewStringUTF(env, "Failed to open file");    }    size = fread(buffer,sizeof(char),1024,fd);    fclose(fd);return (*env)->NewStringUTF(env, buffer);}#ifdef __cplusplus}#endif#endif

使用ndk-build命令编译,函数getString()就可以使用了。

在java里面的调用代码如下:

package com.example.minardshake;import com.example.jni.minardJni;import android.os.Bundle;import android.app.Activity;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class MainActivity extends Activity {//加载我定义的sostatic{System.loadLibrary("MinardJni");}private TextView txt_showMemInfo = null;private Button btn_click = null;minardJni jni = null;//我的jni类名@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initControl();}public void initControl(){txt_showMemInfo = (TextView)findViewById(R.id.txt_showMemInfo);btn_click = (Button)findViewById(R.id.btn_click);btn_click.setOnClickListener(new btnClick());jni = new minardJni();}public class btnClick implements OnClickListener{@Overridepublic void onClick(View view) {// TODO Auto-generated method stubswitch (view.getId()) {case R.id.btn_click:txt_showMemInfo.setText(jni.getString());txt_showMemInfo.append("I am minard.this is my all meminfo.");break;default:break;}}}}

以上基本就完成了。附上源码地址点击打开下载链接(文章中包括一个广播事件的监听,可以忽略)。








0 0
原创粉丝点击