JNI使用(1)

什么是JNI:
         JNI java本地开发接口

      JNI 是一个协议

     这个协议用来沟通java代码和外部的本地代码(c/c++).

   通过这个协议,java代码就可以调用外部的c/c++代码

   外部的c/c++代码也可以调用java代码


步奏:
        1.配置ndk环境,windows -->Preferences -->Android -->NDK -->NDK Location,这在个输入栏中添加android-ndk-r9在硬盘上的路径.
            如图:
                
        2.在Java代码中写上带有native关键字的方法:public native int add(int a,int b);

        3.利用ndk工具生成jni文件夹
          右键工程Android Tools -->   Add Android Native Support -->library name  在输入栏中输入动态链接库文件名,后缀名默认为.so ,这里输入为third.因为在Android下    
           的Linux环境下的动态链接库文件为.so,而在windows下为.dal文件. 操作成功后会在工程目录下生成jni文件夹,文件夹下有Android.mk文件和刚才输入third.cpp,若是通
           过jni调用c代码的就将后缀名改为c即可,同时Android.mk文件中的LOCAL_SRC_FILES := third.cpp也更改为LOCAL_SRC_FILES := third.c,该文件中还有一个宏定 LOCAL_MODULE    := third,就是动态链接库.so文件的名字为third.而在third文件中自动包含一个头文件include<jni.h>,该头文件是一些Java与C/C++之间数据类
      型转换的C函数.
      如图所示:
          
                       


           
        4.由于在JAva代码中已经写了public native int add(int a,int b);方法
            若是jdk1.6(包含)一下的环境,则需在工程目录下的classes文件下用命令行的方式输入     javah 包名和类名
            若是1.6以上的环境则在工程源文件src目录下输入    javah 包名 和类名
            如图所示;
                
            在eclips下刷新刚才的工程目录就会在src目录下看见com_itheima_thirdjni_MainActivity.h头文件
            如图所示:
                

            然后将该文件移动到jni文件夹下,并在.c文件中拷贝
           JNIEXPORT jint JNICALL Java_com_itheima_thirdjni_MainActivity_add(JNIEnv *, jobjectjintjint);
       该方法,删除JNIEXPORT与JNICALL(也可以不删),最后就是
          jint  Java_com_itheima_thirdjni_MainActivity_add(JNIEnv *, jobjectjintjint)
           {
         
          }
 添加四个变量名JNIEnv *env, jobject objjint ajint b,
 第一个env是jni.h头文件中的结构体指针变量,可以通过该指针调用结构体里面的函数指针进而调用C/C++中相应的方法.
 第二个obj就是刚才src目录下通过javah命令中的类名所对应的对象,这两个参数必须有,是系统自动就带的,
 而后面两个参数是在java中用native关键字申明的方法中的参数变量.Jint是返回类型,与native方法所对应
         jint  Java_com_itheima_thirdjni_MainActivity_add(JNIEnv *env, jobject obj, jint a, jint b){

         }
      然后在{}中写入c代码,并且可以调用jni.h中的函数,为了防止jni.h头文件找不到可以再
            配置 右键工程 properties c/c++ general path and symbols incluse 输入D:\android-ndk-r9\platforms\android-9\arch-arm\usr\include(ndk文件中的路径)
            如图所示:只有在第4个步奏完了之后才可以做该操作,否则右键工程属性是没有C/C++General这个目录的,该操作完之后会在jni文件夹下走动包含jni.h头文件
                        
            
         5.然后在jni文件夹下的.c/cpp文件中就可以调用c/c++的代码了.

         6.最后在java代码中用static代码快写入System.loadLibrary(类库名.so),类库名就是在第3步中图片所指的内容,就可以加载.so类库了,该文件在libs/armeabi目录下,也是在    
            第4个操作后生成的.
            由第4步操作生成的类库文件是在Arm   CPU和Linux操作系统下运行的,在其它平台下还有mips  CPU和    intel的x86 CPU,在不同平台下需要的.os文件也是不同的,        
            因此可以再jni文件夹下创建Application.mk文件,必须是该名字,里面写入APP_ABI := all  即可
         7.运行Android程序,会自动在libs目录下生成如下.so文件,是在不同平台下生成的.so文件,这就是所谓的交叉编译
                
         8.
常见错误

1, 01-26 06:26:21.308: E/AndroidRuntime(1417): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load check: findLibrary returned null

    1.忘记写 System.loadLibrary(“xxx”); 注:libxxx.so

  2.找不到对应cpu型号的.so文件                                                                                              
  9.程序运行顺序:
    1.加载.so文件通过System.loadLibrary("类库名.so"),通过libs下的不同版本并根据不同平台加载.so文件
    2.调用java中native方法
    3.由native方法去掉用jni文件夹中的C/C++文件中与native方法相对应的函数,然后执行函数中的JNI代码返回结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值