关于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 __cplusplus
extern "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 {
//加载我定义的so
static{
System.loadLibrary("MinardJni");
}
private TextView txt_showMemInfo = null;
private Button btn_click = null;
minardJni jni = null;//我的jni类名
@Override
protected 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{
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
switch (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;
}
}
}
}
以上基本就完成了。附上源码地址点击打开下载链接(文章中包括一个广播事件的监听,可以忽略)。