android如何使用自己定义JNI接口,以及NDK环境建设和使用的工具。

一、建筑环境:

        1、需要的工具:

               A、cygwin    (在windows下使用LINUX系统)                                                                    http://www.cygwin.com

               B、android-ndk-1.6_r1-windows (主要是起到将C或C++编译成动态库的作用)   http://dl.google.com/android/ndk/android-ndk-1.6_r1-windows.zip

               C、eclipse(建立ANDROIDproject的软件。使用ANDROID的童鞋应该早就安装了。在这不复述)。

      

         2、安装cygwin  

               A、从上面指定的网址下载cygwin  软件。点击cygwin.exe进行安装。

               B、安装软件执行起来后,通常採用默认情况。一直点击下一步就好。

     


    

   上面这个图有三个选项,一般默认就好,第二个是说,仅仅下载不安装,下载后须要手动安装;第三个是说。在下载到本地后再进行安装。



        这个是指该软件的安装路径,一般不须要更换。



    这个路径是指下载的内容保存在什么位置,这个自己能够指定。




让其自己主动下载,再点击“下一步”。


这个是须要选择下载内容的地址,之前在这选择N次。后面安装都失败了,假设想多选择几个下载地址,能够按住“ctrl”进行选择,建议不要多选。多选后会创建多个目录

假设失败就重头開始,选择新的地址,重复安装。才干成功。


让其自己主动下载,再点击“下一步”。



这一步是要选择须要安装的内容。一般像GNU   gcc   g++  等经常使用工具须要安装。当然也能够所有安装。但所有安装的时间会非常长。

最后下载完毕后会自己主动安装,点击完毕就好。


3、验证cygwin成功安装。

     执行安装好的cygwin软件,进去输入gcc -v     make -v   g++ -v 等命令。看能否得到其版本号信息。如不能得到。说明有些工具没有安装,须要又一次安装

    未安装的工具(其方法跟前面一样,仅仅是选择你未安装的工具就可以)。

   

至此cygwin软件算是安装完毕,假设后期使用到新的命令,假设无法使用。则须要又一次安装未安装的工具。



4、安装NDK

     a、依照前面给的地址,下载NDK工具软件。

     b、将该工具软件解压到某路径下(尽量不要是中文路径,由于在cygwin环境下使用中文不方便)E:androidNDKandroid-ndk-1.6_r1-windowsandroid-ndk-1.6_r1

     c 、打开cygwin软件,首先进入根文件夹下,在使用cd  cygdrive/e/androidNDK/android-ndk-1.6_r1-windows/android-ndk-1.6_r1/ 进入该文件夹下

     d、输入build/host-setup.sh 假设出现以下信息说明就成功安装。

      


    5、环境搭建好后。当然就是去编写一个JNI接口怎样调用.SO文件了。过程例如以下

          A、e/androidNDK/android-ndk-1.6_r1-windows/android-ndk-1.6_r1/  文件夹下有一个APP文件夹。专门是放NDKproject的,所以我们

在创建ANDROIDproject时指定location位置为e/androidNDK/android-ndk-1.6_r1-windows/android-ndk-1.6_r1/APP/first_jni

创建一个JNI接口类Jin.java,内容例如以下:

                 package example.dialog.test; 


                 public class Jin {
                public native int add();
                public native String getString();
                }

           B、执行DOS命令窗体。进入上述文件的文件夹下,使用 javac  Jin.java  生成Jin.class类

           C、执行javah  -jni  包名+Jin.class 命令,最后生成     包名+Jin.h

            D、在ANDROIDproject文件夹下创建Jni文件夹,并将前面生成的 包名+Jin.h文件拷贝到该文件夹下,再在此文件夹下新建.c文件,用来实现 包名+Jin.h中的函数。

   实现例如以下:

                    #include<stdio.h>
   #include<stdlib.h>
                   #include"example_dialog_test_Jin.h"
           int add()
   { 
 int x,y;
 x=100;
 y=100;
 return x*y;
   }
JNIEXPORT jint JNICALL Java_example_dialog_test_Jin_add(JNIEnv *env,jobject thiz){
        return add();
}
JNIEXPORT jstring JNICALL Java_example_dialog_test_Jin_getString(JNIEnv *env,jobject thiz){
         (*env)->NewStringUTF(env,"hello world in c!!!");
}

              E、JNI通过调用动态链接库(WINDOWS下是DLL,LINUX下是SO)来实现对CC++方法的调用。因此如今我们就须要将上面写的

                      C代码编译成SO文件。

                      编译时须要再从个文件: Android.mk和Application.mk.这两个文件的存放文件夹是有讲究的。前者存在与C文件一个文件夹下,后者

                      存在ANDROIDproject根文件夹下。

                      Android.mk  文件的内容一般能够去其他project中去复制过来,内容例如以下:

                       LOCAL_PATH := $(call my-dir)            //LOCAL_PATH表示此时位于project文件夹的根文件夹,(call my-dir)返回当前文件夹位置。
                       include $(CLEAR_VARS)                    
       LOCAL_MODULE    := NewJNI            //用来区分 Android.mk中的每个模块。文件名称必须唯一。不能有空格,这个是你以后库文件生成的文件名称,编译器会自己主动 给你加上前缀lib和后缀.so. 
                       LOCAL_SRC_FILES := example_dialog_test_Jin.c       //编译时的C文件
                       include $(BUILD_SHARED_LIBRARY)                             //表明生成动态库

                      


Application.mk中的内容:

                APP_PROJECT_PATH := $(call my-dir)/firstjni-test
APP_MODULES      := NewJNI
                                         //些处的值要与Android.mk中的LOCAL_MODULE中的值一样。         

                        最后启动cygwin进入NDK文件夹。输入make APP=frist_jin,出现以下的界面表示编译成功。

即在E:androidNDKandroid-ndk-1.6_r1-windowsandroid-ndk-1.6_r1appsfirst-jnifirstjni-testlibsarmeabi  该文件夹下生成了libNewJNI.so动态库。

                       


              F、接着我们将在安卓应用程序中使用该库,在上述project下新建一个MyJni.java类,其内容例如以下:

                     package example.dialog.test;
     import android.app.Activity;
    import android.os.Bundle;
    import android.widget.TextView;
            import example.dialog.test.Jin;
                    public class MyJni extends Activity{
                          private TextView textview;
                          static{
                                System.loadLibrary("NewJNI");
                          }
                      @Override
                      protected void onCreate(Bundle savedInstanceState) {
              // TODO Auto-generated method stub
             super.onCreate(savedInstanceState);
             setContentView(R.layout.main);
             Jin jni = new Jin();
             int result = jni.add();
             textview =(TextView)findViewById(R.id.tv);
            textview.setText("add()="+result+" getString()="+jni.getString());
                   }
                     }

              最后执行应用程序,结果例如以下 图所看到的:

                    


              整个project的文件夹例如以下 :

             



               到此,整个过程都已经结束了,可以做到这样,也说明你对JNI接口以及NDK工具的使用算是入门了。

              当然在整个过程中会有一些问题,我主要遇到过下面问题:

              1、安装好cygwin软件后,用build/host-setup.h时出现GNU无法使用。后来查明了原因是在装cygwin时没有下载GNU以及后面使用的make。又一次下载就好。

              2、在使用javah -jni  包名+类名时(且不须要加.class后缀),出现无法找到包名+类名 ,原因是文件夹的层次不正确。应该在包名的上级文件夹使用该命令。

              3、在使用make APP=项目目录(而不是生成so文件名称)。

              4、在执行模式似是当,被赋予了。他说,参考so文件是空的。后来查询到,由于与第一模拟器 inter atom(x86)的,和.so文件属于ARM系列,更换成功后。


原文地址:https://www.cnblogs.com/lcchuguo/p/5043342.html