Android中JNI使用详解(1)---Eclipse中NDK配置So文件生成

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lsf1025995457/article/details/51842989

1NDK下载和配置

NDK下载地址:http://www.androiddevtools.cn/

NDK下载完成后,选择Eclipse上方Window菜单Preferences - Android - NDK NDK Location中配置NDK绝对路径。

`

2、安装下载CDT插件 

选择Eclipse上方的Help菜单-Inatall New SoftWareWork with:后输入CDT - http://download.eclipse.org/tools/cdt/releases/juno 然后等待勾选CDT Main Features和 CDT Optional Features然后点击Next,等下载完成重启Eclipse即可。 


3、查看JNI示例

在下载的NDKsamples目录下有hello-jni等例子,可通过运行例子来了解jni工作原理。先观察jni文件夹,一般里面有三个文件,分别为Android.mkApplication.mkjni.c文件;

扫描二维码关注公众号,回复: 4055570 查看本文章


4Android.mk介绍

Android.mk:用于配置编译生成的so库名、引用的头文件(.h文件)、需要编译的.c文件和.a静态库文件等。要掌握jni,必须了解Android.mk里面变量的作用和规范。


1LOCAL_PATH:  这个变量用于给出当前文件的路径。 
       必须在 Android.mk 的开头定义,可以这样使用:LOCAL_PATH := $(call my-dir) 
       如当前目录下有个文件夹名称 src,则可以这样写 $(call src),那么就会得到 src 目录的完整路径 
       这个变量不会被$(CLEAR_VARS)清除,因此每个 Android.mk 只需要定义一次(即使在一个文件中定义了几个模块的情况下)。 


      (2LOCAL_MODULE: 这是模块的名字,它必须是唯一的,而且不能包含空格。 
       必须在包含任一的$(BUILD_XXXX)脚本之前定义它。模块的名字决定了生成文件的名字。 


      (3LOCAL_SRC_FILES:  这是要编译的源代码文件列表。 
       只要列出要传递给编译器的文件,因为编译系统自动计算依赖。注意源代码文件名称都是相对于 LOCAL_PATH的,你可以使用路径部分,例如: 
        LOCAL_SRC_FILES := foo.c toto/bar.c\ Hello.c 
       文件之间可以用空格或Tab键进行分割,换行请用"\" 
       如果是追加源代码文件的话,请用LOCAL_SRC_FILES += 
       注意:可以LOCAL_SRC_FILES := $(call all-subdir-java-files)这种形式来包含local_path目录下的所有java文件。 


    (4LOCAL_C_INCLUDES:  可选变量,表示头文件的搜索路径。 
        默认的头文件的搜索路径是LOCAL_PATH目录。 


    (5LOCAL_STATIC_LIBRARIES: 表示该模块需要使用哪些静态库,以便在编译时进行链接。 


    (6LOCAL_SHARED_LIBRARIES:  表示模块在运行时要依赖的共享库(动态库),在链接时就需要,以便在生成文件时嵌入其相应的信息。 
       注意:它不会附加列出的模块到编译图,也就是仍然需要在Application.mk 中把它们添加到程序要求的模块中。 


    (7LOCAL_LDLIBS:  编译模块时要使用的附加的链接器选项。这对于使用‘-l’前缀传递指定库的名字是有用的。 
       例如,LOCAL_LDLIBS := -lz表示告诉链接器生成的模块要在加载时刻链接到/system/lib/libz.so 
       可查看 docs/STABLE-APIS.TXT 获取使用 NDK发行版能链接到的开放的系统库列表。 


     (8)LOCAL_MODULE_PATH 和 LOCAL_UNSTRIPPED_PATH 
       在 Android.mk 文件中, 还可以用LOCAL_MODULE_PATH LOCAL_UNSTRIPPED_PATH指定最后的目标安装路径
       不同的文件系统路径用以下的宏进行选择: 
       TARGET_ROOT_OUT:表示根文件系统。 
       TARGET_OUT:表示 system文件系统。 
       TARGET_OUT_DATA:表示 data文件系统。 
       用法如:LOCAL_MODULE_PATH :=$(TARGET_ROOT_OUT) 
       至于LOCAL_MODULE_PATH LOCAL_UNSTRIPPED_PATH的区别,暂时还不清楚。 


   (9LOCAL_JNI_SHARED_LIBRARIES:定义了要包含的so库文件的名字,如果程序没有采用jni,不需要 
        LOCAL_JNI_SHARED_LIBRARIES := libxxx 这样在编译的时候,NDK自动会把这个libxxx打包进apk; 放在youapk/lib/目录下 


5Application.mk介绍

Application.mk:用于配置JNI生成该CPU使用so的文件格式如下:

APP_ABI := armeabi armeabi-v7a x86 arm64-v8a x86_64 mips mips64

TARGET_CPU_API :=armeabi armeabi-v7a x86 arm64-v8a x86_64 mips mips64

或者 配置所有

APP_ABI := all


6.c文件介绍

.c文件是Jni中主要编译文件,下面以hello-jni.c进行介绍;

jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}

这个函数名根据src下的HelloJni,java中的函数public native String stringFromJNI();生成的。命名规则为:

Java_(固定开头)com_example_hellojni(_连接的包名)_HelloJni(类名)_stringFromJNI(函数名)

 

这个函数的生成可以使用javah的命令:用命令行方式进入工程目录的bin\classes目录下,运行javah com.example.hellojni.HelloJni,就会把所有native的函数都按规则生成在一个名为HelloJni.h的头文件里。


7新建并配置一个新的Builder

    1) 点击Project->Properties->Builders->New,新建立一个Builder。在弹出的对话框上面点击Program,点击OK

    2) 在弹出的对话框【Edit Configuration】中,配置选项卡【Main】:

               Location中需要填入nkd-build.cmd的路径(NDK安装目录下)。

               WorkingDiretcoty中需要填入HelloJni的工程根目录。

    3) 在【EditConfiguration】中,配置选项卡【Refresh】:

              勾选“Refresh resources upon completion”,

              勾选“The entire workspace”,

              勾选“Recuresively include sub-folders”。

    4)在【EditConfiguration】中,配置选项卡【Build Options】:

             勾选“After a Clean””,

             勾选“During manual builds”,

             勾选“During auto builds,

             勾选“Specify working set of relevant resources”。

             点击“Specify Resources…”勾选TestNDK工程的“jni“目录,Finish

      保存设置,点击OK


8、生成so文件的方法

   由于我们勾选了“During auto builds”,所以在工程有所改变的时候,so文件便会自动编译,正确生成以后就能在工程目录下发现多了两个文件夹,文件夹libs\armeabi目录下生成了一个叫libhello-jni.so的文件。至此,使用NDK生成so文件的工作就完成了。


9so文件的调用

    在HelloJni.java文件中有一段代码:

    static {
        System.loadLibrary("hello-jni");
    }

    使用loadLibrary就可以加载该so文件了,加载的时候不需要写libhello-jni.so,只要写hello-jni就可以了。

猜你喜欢

转载自blog.csdn.net/lsf1025995457/article/details/51842989