1、javac 生成 .class文件
2、javah -jni 生成 .h文件
3、根据.h文件,修改.c文件。
1、这里的规则是指:
Android.mk
文件。2、可以编译为动态库,也可以编译为静态库。
1、NDK下载:
https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip
这里下载的是目前最新版本的:r14b
。
2、配置环境
下面进行环境配置
在ubuntu14.04
下新建/usr/local/ndk
目录,
① :把刚才下载的ndk源码包,拷贝到 该目录下,解压。
②:打开~/.bashrc
文件,在文件最后,添加如下内容:
export PATH=/usr/local/ndk/android-ndk-r14b/:$PATH
使用source ~/.bashrc
命令,更新环境变量。
3、测试NDK
ubuntu下使用如下命令,测试ndk是否配置正确:
root@ubuntu:/neo/c# ndk-build -v
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
root@ubuntu:/neo/c#
如上所示,ndk
环境配置完成。
为了便于理解,在JNI的基础上编译动态库。
JNI程序的参考链接:
https://blog.csdn.net/weixin_38184741/article/details/91461231
使用ndk-build工具进行ndk编译时,需要按照配置文件中的规则进行编译。这里说的配置文件就是Android.mk文件。
Android.mk的内容为:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= HelloWorldNDK
LOCAL_SRC_FILES:= HelloWorld.c
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_LDLIBS := -llog
#include $(BUILD_STATIC_LIBRARY)
include $(BUILD_SHARED_LIBRARY)
其中:
LOCAL_PATH:= $(call my-dir)
表示当前目录。
include $(CLEAR_VARS)
表示清除之前的配置。一般和
include $(BUILD_STATIC_LIBRARY)
include $(BUILD_SHARED_LIBRARY)
include $(PREBUILT_STATIC_LIBRARY)
include $(PREBUILT_SHARED_LIBRARY)
配合使用(应该还有其他的,我没有深入研究。我的理解是清除之前模块的配置(LOCAL_PATH
除外))。
LOCAL_MODULE
表示编译出的库的名称
LOCAL_SRC_FILES
表示源文件的路径以及命令
LOCAL_EXPORT_C_INCLUDES
表示头文件所在目录。
LOCAL_EXPORT_LDLIBS
表示需要加载的标准库。-llog
表示加载 liblog
库,用于输出调试信息。
include $(BUILD_SHARED_LIBRARY)
表示编译成动态库,
include $(BUILD_STATIC_LIBRARY)
表示编译成静态库,这里我们给屏蔽了。静态库一般都很大。
下面编译NDK动态库,配置文件就是上面所示。
root@ubuntu:~/ken/jni# ndk-build
[arm64-v8a] Compile: HelloWorldNDK <= HelloWorld.c
In file included from /root/ken/jni/HelloWorld.c:1:
/root/ken/jni/jni.h:45:10: fatal error: 'jni_md.h' file not found
#include "jni_md.h"
^
1 error generated.
make: *** [/root/ken/obj/local/arm64-v8a/objs/HelloWorldNDK/HelloWorld.o] Error 1
显示找不到jni中引用的头文件,之前我们是使用-I参数,加载头文件路径解决的。
现在我们可以把jni.h文件删除掉,因为ndk的库中也有jni.h头文件。
删除jni.h文件之后,继续编译。
root@ubuntu:~/ken/jni# ndk-build
[arm64-v8a] Compile: HelloWorldNDK <= HelloWorld.c
[arm64-v8a] SharedLibrary : libHelloWorldNDK.so
[arm64-v8a] Install: libHelloWorldNDK.so => libs/arm64-v8a/libHelloWorldNDK.so
[x86_64] Compile: HelloWorldNDK <= HelloWorld.c
[x86_64] SharedLibrary : libHelloWorldNDK.so
[x86_64] Install: libHelloWorldNDK.so => libs/x86_64/libHelloWorldNDK.so
[mips64] Compile: HelloWorldNDK <= HelloWorld.c
[mips64] SharedLibrary : libHelloWorldNDK.so
[mips64] Install: libHelloWorldNDK.so => libs/mips64/libHelloWorldNDK.so
[armeabi-v7a] Compile thumb : HelloWorldNDK <= HelloWorld.c
[armeabi-v7a] SharedLibrary : libHelloWorldNDK.so
[armeabi-v7a] Install: libHelloWorldNDK.so => libs/armeabi-v7a/libHelloWorldNDK.so
[armeabi] Compile thumb : HelloWorldNDK <= HelloWorld.c
[armeabi] SharedLibrary : libHelloWorldNDK.so
[armeabi] Install: libHelloWorldNDK.so => libs/armeabi/libHelloWorldNDK.so
[x86] Compile: HelloWorldNDK <= HelloWorld.c
[x86] SharedLibrary : libHelloWorldNDK.so
[x86] Install: libHelloWorldNDK.so => libs/x86/libHelloWorldNDK.so
[mips] Compile: HelloWorldNDK <= HelloWorld.c
[mips] SharedLibrary : libHelloWorldNDK.so
[mips] Install: libHelloWorldNDK.so => libs/mips/libHelloWorldNDK.so
root@ubuntu:~/ken/jni#
发现不是在当前目录下生成库文件,而是在前一目录下。这个不符合我们的习惯。
ndk-build clean
后,添加参数,继续编译:
root@ubuntu:~/ken/jni#
root@ubuntu:~/ken/jni# ndk-build clean
[arm64-v8a] Clean : HelloWorldNDK [arm64-v8a]
[arm64-v8a] Clean : stdc++ [arm64-v8a]
[x86_64] Clean : HelloWorldNDK [x86_64]
[x86_64] Clean : stdc++ [x86_64]
[mips64] Clean : HelloWorldNDK [mips64]
[mips64] Clean : stdc++ [mips64]
[armeabi-v7a] Clean : HelloWorldNDK [armeabi-v7a]
[armeabi-v7a] Clean : stdc++ [armeabi-v7a]
[armeabi] Clean : HelloWorldNDK [armeabi]
[armeabi] Clean : stdc++ [armeabi]
[x86] Clean : HelloWorldNDK [x86]
[x86] Clean : stdc++ [x86]
[mips] Clean : HelloWorldNDK [mips]
[mips] Clean : stdc++ [mips]
root@ubuntu:~/ken/jni# ndk-build NDK_PROJECT_PATH=.
Android NDK: Your APP_BUILD_SCRIPT points to an unknown file: ./jni/Android.mk
/usr/local/ndk/android-ndk-r14b/build/core/add-application.mk:198: *** Android NDK: Aborting.... Stop.
root@ubuntu:~/ken/jni# ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
[arm64-v8a] Compile: HelloWorldNDK <= HelloWorld.c
[arm64-v8a] SharedLibrary : libHelloWorldNDK.so
[arm64-v8a] Install: libHelloWorldNDK.so => libs/arm64-v8a/libHelloWorldNDK.so
[x86_64] Compile: HelloWorldNDK <= HelloWorld.c
[x86_64] SharedLibrary : libHelloWorldNDK.so
[x86_64] Install: libHelloWorldNDK.so => libs/x86_64/libHelloWorldNDK.so
[mips64] Compile: HelloWorldNDK <= HelloWorld.c
[mips64] SharedLibrary : libHelloWorldNDK.so
[mips64] Install: libHelloWorldNDK.so => libs/mips64/libHelloWorldNDK.so
[armeabi-v7a] Compile thumb : HelloWorldNDK <= HelloWorld.c
[armeabi-v7a] SharedLibrary : libHelloWorldNDK.so
[armeabi-v7a] Install: libHelloWorldNDK.so => libs/armeabi-v7a/libHelloWorldNDK.so
[armeabi] Compile thumb : HelloWorldNDK <= HelloWorld.c
[armeabi] SharedLibrary : libHelloWorldNDK.so
[armeabi] Install: libHelloWorldNDK.so => libs/armeabi/libHelloWorldNDK.so
[x86] Compile: HelloWorldNDK <= HelloWorld.c
[x86] SharedLibrary : libHelloWorldNDK.so
[x86] Install: libHelloWorldNDK.so => libs/x86/libHelloWorldNDK.so
[mips] Compile: HelloWorldNDK <= HelloWorld.c
[mips] SharedLibrary : libHelloWorldNDK.so
[mips] Install: libHelloWorldNDK.so => libs/mips/libHelloWorldNDK.so
root@ubuntu:~/ken/jni#
root@ubuntu:~/ken/jni# ls
Android.mk HelloWorld.c HelloWorld.class HelloWorld.h HelloWorld.java libHelloWorld.so libs obj
root@ubuntu:~/ken/jni#
由上面可以,我们在使用ndk-build
时,添加了两个参数NDK_PROJECT_PATH
和APP_BUILD_SCRIPT
,用于指定工程路径,以及配置文件路径。
查看编译出的库的情况:
root@ubuntu:~/ken/jni/libs# file */*
arm64-v8a/libHelloWorldNDK.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a63502fc8bb3907cd4f122d6aa1867b7423dc7dd, stripped
armeabi/libHelloWorldNDK.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=56d98623f4f90a52ca681bd88768c520a999b722, stripped
armeabi-v7a/libHelloWorldNDK.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=f66ea129183665d8384f0df51dbe3c655890b35e, stripped
mips64/libHelloWorldNDK.so: ELF 64-bit LSB shared object, MIPS, version 1 (SYSV), dynamically linked, BuildID[sha1]=087e1f1cd4859a68c7ea2a06c6932cd10cbb87dc, stripped
mips/libHelloWorldNDK.so:ELF 32-bit LSB shared object, MIPS, MIPS32 version 1 (SYSV), dynamically linked, BuildID[sha1]=d49923384cc67942af6f3b1dd83fa7a89a4c1139, stripped
x86_64/libHelloWorldNDK.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=fa7710bd5ce6964995bcc8be52aadcd422cf8acb, stripped
x86/libHelloWorldNDK.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=f91da4f4c467ebd8cf4b28d237336a48a719d308, stripped
root@ubuntu:~/ken/jni/libs# cd ../obj/
root@ubuntu:~/ken/jni/obj# tree */*
local/arm64-v8a
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/armeabi
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/armeabi-v7a
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/mips
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/mips64
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/x86
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/x86_64
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
14 directories, 21 files
root@ubuntu:~/ken/jni/obj#
此时编译出的库就可以给app调用了。