现在的位置: 首页 > 综合 > 正文

JNI详细教程

2013年09月18日 ⁄ 综合 ⁄ 共 3978字 ⁄ 字号 评论关闭

搞了三天,终于有点眉目了,共享给大家

android调用c++代码

至于ndk环境这里不讲了(http://blog.csdn.net/yinzhengbo/article/details/7268207


先简述一下实现的功能,增加学生,修改学生信息,查询所有学生信息,根据名字查找学生


1、首先在项目里新建Student实体类包含字段(name,sex,age),

       调用Jni方法的类StudentToJNI包含方法(addStu(Student stu),upStu(Student stu),getStu(String name),getStus)


2、cmd -> javac(编译StudentToJNI.java文件) 生成字节码文件


3、生成头文件(javah)  cd至项目classess目录下 执行  javah -jni  包名+类名(类名不要后缀),会在classes生成一个.h的文件


4、项目根目录下新建jni文件夹,复制 .h文件至jni文件夹下,然后找到ndk的安装目录找到android.mk,Application.mk文件夹一同放在jni目录下,注意如果使用c++里的库需要在Application.mk文件中加入(APP_STL:= stlport_shared)

至于两个文件内容其它的用法,这里就不在描述(goolgle)


5、jni文件夹下新建.cpp文件,最好名称与头文件一致,然后拷贝头文件里的所有函数至cpp文件夹内,并且导入头文件(#include<name.h>),当然也要导入jni.h头文件,其实我们主要做的是就是通过jni把java传进来的类型,转换成c++需要的类型,然后把c++返回的值通过jni转换成java所需要的类型。jni.h头文件里提供了很多转换的方法以及取值的方法,具体大家可以打开ndk安装目录(platforms\android-9\arch-arm\usr\include)目录下查看jni.h头文件


6、具体实现(文件:android.mk,Application.mk,jniTest.h,jniTest.cpp):

        主要是实现jniTest.cpp文件

        (1)、引用必要的头文件(jni.h,jniTest.h,vector),引入命名空间(using namespace std;)


        (2)、定义一个结构,结构里的内容和java类中Student里的字段一样(struct student { char * name;int age,int sex};)(分号必须有)、定义一个向量,用来保存录入的学生信息,(由于是用户输入,长度不固定所以采用向量来保存)(vector<student>
stus)


        (3)、定义JstringTosString方法用于jString类型转换成char指针类型 具体代码goolgle,jni会把java传进来的对象类型转换成jni相对应的类型。如(java
  string=jni  jstring 、java Student = jni jobject。。。。。。)


        (4)、增加学生信息:addStu(JNIEnv *env, jobject obj, jobject valObj)

              

//获取jclass对象
jclass cls=env->GetObjectClass(valObj);
//GetFieldID方法用到取到jclass中的name字段。参数列表(jclass对象,字段名称,字段类型),这点类似于java的反射
//GetObjectField方法从传进来的jobject对象valObj里取到指定字段的值。参数列表(jobject对象,jfieldID对象)注意类型转换;
jstring name=(jstring)env->GetObjectField(valObj,env->GetFieldID(cls,"name","Ljava/lang/String;"));
jint age=(jint)env->GetObjectField(valObj,env-> GetFieldID(cls,"age","I"));
jint sex=(jint)env->GetObjectField(valObj,env->GetFieldID(cls,"sex","I"));
//创建一个结构类型的对象 jstringToString方法用于把jstring类型转换成char *
student stu={jstringTostring(env,name),(int)age,(int)sex};
//往向量的未尾增加一个对象
stus.push_back(stu);

 (5)、修改学生信息:upStu(JNIEnv
*env, jobject obj, jobject valObj)

     

         jclass cls=env->GetObjectClass(objValue);
jstring name=(jstring)env->GetObjectField(objValue,env->GetFieldID(cls,"name","Ljava/lang/String;"));
jint sex=(jint)env->GetObjectField(objValue,env->GetFieldID(cls,"sex","I"));
jint age=(jint)env->GetObjectField(objValue,env->GetFieldID(cls,"age","I"));

char * searchName=jstringTostring(env,name);

for(int i=0;i<stus.size();i++)
{
student stu=stus.at(i);
if(strcmp(stu.name,searchName)==0)
{
stus.at(i).sex=(int)sex;
stus.at(i).age=(int)age;
}
}


 (6)、查询学生信息:getStu(JNIEnv
* env, jobject obj, jstring str)

       

 const char *nameStr=env->GetStringUTFChars(str,0);
jclass objectClass=(env)->FindClass("com/myjni/activity/Student");
jfieldID name=env->GetFieldID(objectClass,"name","Ljava/lang/String;");
jfieldID sex=env->GetFieldID(objectClass,"sex","I");
jfieldID age=env->GetFieldID(objectClass,"age","I");

for(int i=0;i<stus.size();i++)
{
student stu=stus.at(i);
if(strcmp(stu.name,nameStr)==0)
{
env->SetObjectField(obj,name,env->NewStringUTF(stus.at(i).name));
env->SetIntField(obj,sex,stus.at(i).sex);
env->SetIntField(obj,age,stus.at(i).age);

}
} 
return obj;


(7)、获取所有学生信息:getStus(JNIEnv * env, jobject obj)


class objClass = (env)->FindClass("java/lang/Object");
jobjectArray args=0;
jsize len=stus.size();
args=env->NewObjectArray(len,objClass,0);
jclass objectClass=(env)->FindClass("com/myjni/activity/Student");
jfieldID name = (env)->GetFieldID(objectClass,"name","Ljava/lang/String;");
jfieldID age = (env)->GetFieldID(objectClass,"age","I");
jfieldID sex = (env)->GetFieldID(objectClass,"sex","I");

for(int i=0;i<len;i++)
{
jobject tempObj=env->AllocObject(env->GetObjectClass(obj));
student stu=stus.at(i);
env->SetObjectField(tempObj,name,env->NewStringUTF(stus.at(i).name));
env->SetIntField(tempObj,age,stu.age);
env->SetIntField(tempObj,sex,stu.sex);
env->SetObjectArrayElement(args,i,tempObj);
}

return args;

7、java代码调用


 static{
	System.loadLibrary("stlport_shared");
	System.loadLibrary("HW");
}
StudentToJNI jni=new StudentToJNI();
jni.add(new Student());
jni.update(new Student());
jni.getStu("tom");
jni.getStus();

源码下载

自己写的额罗事方块,因时间问题,只完成了一部分

贪吃蛇











抱歉!评论已关闭.