Android NDK 学习笔记

来源:互联网 发布:同花顺炒股软件免费版 编辑:程序博客网 时间:2024/05/21 14:56

转: http://blog.renren.com/GetEntry.do?id=718959269&owner=228440950

上个星期,导师看我们闲的慌,让我们实现Android平台下的socket通信,实现两端通信。采用NDK方法,java编写界面,c编写socket实体。从此开始了我们一个多星期的磨难。本来以为是一个很简单的程序,编写的时候才发现很麻烦,遇到的问题不断,正常问题有,诡异的问题也不少。不过的确增长了不少知识,现在将一些学习到的东西记录下来。

NDK的安装过程就不说了,网上都有。只是在一个文件中增加一句话就可以搞定,很简单。接下来的才是重点。

1.javah 命令

   这个命令是用于生成*.c文件的头文件,同时最重要的是,生成java中的本地方法在*.c文件中的函数名。若是你对这个函数写法不清楚的话,可以试试这个命令。使用过程如下:

     1.将用javac命令将定义本地方法的java文件编译,生成*.class文件。

     2.退后到工程目录下的src文件中。

     3.终端输入如下命令: javah -jni com.studentmanager.mars.JNI。其中com.studentmanager.mars是完整的包名,JNI是我定义本地方法的文件。注:可不要将继承Activity的那个文件用javac,这是不能编译通过的,可以将本地方法定义到另一个类中。

     4.将在src文件中生成的头文件移到jni文件中,然后在*.c文件中包含这个头文件就可以了。

     截图如下: 

2.javap

   这个命令是用于GetMethodID方法中,显示此java文件中函数的签名。具体意义在后名说明,它的用法如下:

    1.进入工程目录下面的bin目录。之所以进入这个目录是由于,javap这个命令对*.class文件起作用,而继承于Activity的java类的*.class文件就在bin目录中。

    2.在终端输入:javap -s -p com.studentmanager.mars.Client     其中-s是指获得签名,-p是指显示private函数, com.studentmanager.mars是完整包名,Client是你需要访问的文件名。运行截图如下:

3.c访问java中的类成员和方法

   这个在程序开发中非常重要,网上也有很多关于这个的帖子,一般代码如下:

   

   第一行代码的目的是获得一个jclass的对象,有两种获得方式。一种是如图所示的GetObjectClass方法,还有一种是FindClass方法。当使用GetObjectClass方法时,需要具有你所要访问java类的一个实例对象。在系统自动生成的两个函数中的jobject thiz也是一个java类的对象,它是你本地方法定义的那个类的对象。使用FindClass方法的格式如下:

jclass objectClass = (*env)->FindClass(env,"com/studentmanager/mars/MyThread");

其中com/studentmanager/mars是完整包名,MyThread是类的名字。

   第二行代码的意思是获得类对象中name成员函数的ID号,"Ljava/lang/String;"表示它的类型为String。

   第三行代码的意思是通过这个ID号获取name成员的值。

   第四行代码的意思是将jstring类型转换为char * 类型。

    注:使用FindClass方法时,由于com/studentmanager/mars/MyThread替代了类对象,故我们需要重新生成一个类的对象。生成代码如下:

    第一行中的GetMethodID方法和GetFieldID方法的含义类似,就是获得类中方法的ID号。"<init>"是一个特殊的方法,即构造方法。它的写法就是这样,不需要进行改变。若想调用其他的方法,可以在那个位置写入方法的名字即可。

    第二行中的NewObject方法即生成一个新的实例对象。

     若想调用类中的方法的话,在获得了方法的ID号之后,调用Call<type>Method方法,即可。整个代码如下: