我必须在我的Android Studio工程中添加原生文件.so,.mk,.sh,.cpp 。 在eclipse .so文件被添加到libs文件夹和obj文件夹中的其他文件,所有工作正常。 但在Android Studio中,因为我在jniLibs文件夹中添加了.so文件,并在.gradle文件中进行了如下更改
ndk{ abiFilters 'armeabi', 'armeabi-v7a', 'x86' } sourceSets.main { jniLibs.srcDir 'src/main/libs' //set libs as .so's location instead of jniLibs jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk }
下面是我的项目和我需要添加的文件的结构。 有jni和obj文件夹包含本机代码,我必须使用它。
我已经看到可用的链接,但他们已经过时,没有任何工作。 任何帮助表示赞赏。
在做以下更改后logging:
sourceSets.main { jniLibs.srcDir 'src/main/libs' //set libs as .so's location instead of jniLibs jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk } externalNativeBuild { ndkBuild { path 'src/main/jni/Android.mk' } }
日志:
Error while executing 'E:\Android_SDK\ndk-bundle\ndk-build.cmd' with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=E:\folder\sampleapp\app\src\main\jni\Android.mk NDK_APPLICATION_MK=E:\folder\sampleapp\app\src\main\jni\Application.mk APP_ABI=armeabi-v7a NDK_ALL_ABIS=armeabi-v7a NDK_DEBUG=1 APP_PLATFORM=android-16 NDK_OUT=E:/folder/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=E:\folder\sampleapp\app\build\intermediates\ndkBuild\debug\lib APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -n} md "E:\folder\sampleapp\app\build\intermediates\ndkBuild\debug\lib\armeabi-v7a" >NUL 2>NUL || rem copy /b/y "E:\Android_SDK\ndk-bundle\build\\..\prebuilt\android-arm\gdbserver\gdbserver" "E:\folder\sampleapp\app\build\intermediates\ndkBuild\debug\lib\armeabi-v7a\gdbserver" > NUL E:/Android_SDK/ndk-bundle/build//../prebuilt/windows-x86_64/bin/echo.exe [armeabi-v7a] "Gdbserver ": "[arm-linux-androideabi] E:\folder\sampleapp\app\build\intermediates\ndkBuild\debug\lib/armeabi-v7a/gdbserver" E:/Android_SDK/ndk-bundle/build//../prebuilt/windows-x86_64/bin/echo.exe [armeabi-v7a] "Gdbsetup ": "E:\folder\sampleapp\app\build\intermediates\ndkBuild\debug\lib/armeabi-v7a/gdb.setup" E:/Android_SDK/ndk-bundle/build//../prebuilt/windows-x86_64/bin/echo.exe "directory E:/Android_SDK/ndk-bundle/build//../platforms/android-16/arch-arm/usr/include E:/folder/app/src/main/jni E:/Android_SDK/ndk-bundle/build//../sources/cxx-stl/system" >> E:\folder\sampleapp\app\build\intermediates\ndkBuild\debug\lib/armeabi-v7a/gdb.setup E:/Android_SDK/ndk-bundle/build//../prebuilt/windows-x86_64/bin/echo.exe "set solib-search-path E:/folder/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a" > E:\folder\sampleapp\app\build\intermediates\ndkBuild\debug\lib/armeabi-v7a/gdb.setup process_begin: CreateProcess(NULL, "", ...) failed. make: *** No rule to make target `E:/folder/app/src/main/jni/SerialPort.c', needed by `E:/folder/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/objs-debug/serial_port/SerialPort.o'. Stop. Build command failed. Error:executing external native build for ndkBuild E:\folder\sampleapp\app\src\main\jni\Android.mk Build command failed. Error while executing 'E:\Android_SDK\ndk-bundle\ndk-build.cmd' with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=E:\folder\sampleapp\app\src\main\jni\Android.mk NDK_APPLICATION_MK=E:\folder\sampleapp\app\src\main\jni\Application.mk APP_ABI=armeabi-v7a NDK_ALL_ABIS=armeabi-v7a NDK_DEBUG=0 APP_PLATFORM=android-16 NDK_OUT=E:/folder/app/build/intermediates/ndkBuild/release/obj NDK_LIBS_OUT=E:\folder\sampleapp\app\build\intermediates\ndkBuild\release\lib APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -n} make: *** No rule to make target `E:/folder/app/src/main/jni/SerialPort.c', needed by `E:/folder/app/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/serial_port/SerialPort.o'. Stop. process_begin: CreateProcess(NULL, "", ...) failed. Error:executing external native build for ndkBuild E:\folder\sampleapp\app\src\main\jni\Android.mk
首先,确保你的源位置,套件的例子。 你有一些问题。 所有本地文件应该在src/main/
../src/main .........../jni # your cpp, header and mk files .........../jniLibs # your folders with all libs .........../java # other code
然后,确保在Activity,Application等任何Native用法之前,在静态字段中加载您的库。
private static final String LIB_NAME = "libserial_port"; private static final String LIB_NAME_1 = "libzqcom"; static { System.loadLibrary(LIB_NAME); System.loadLibrary(LIB_NAME_1); }
UPD 1:
确保您已经安装Android NDK Source for Native Android项目。
加上GensaGames的答案,如果你有一个.mk文件用于构build本地库,为了将它添加到构build过程中,你必须在模块级的build.gradle文件中指定该文件的path,在android {}块中:
externalNativeBuild { ndkBuild { path 'path/to/Android.mk' } }
需要说明的是,GensaGamesbuild议的目录结构对于Android Studio并不是必须的 – 只要在build.gradle或Android.mk中指定其目录,就可以将.mk和.cpp文件放在任何位置。
我想我已经使用简单的JNI项目在Android Studio中重现了错误。 引发这个特定错误的东西(“make:*** No target …”)对我来说是一个不正确的path到Android.mk的源文件之一。 (如果path是正确的,那么构build就会成功;如果完全保留一个源文件,就会出现链接器错误。)例如,如果我指定了一个不正确的path来源,那么会发生这样的错误:
make: *** No rule to make target `/Users/afarm/AndroidStudioProjects/Mktest/app/src/main/cp/stringdep.cpp', needed by `/Users/afarm/AndroidStudioProjects/Mktest/app/build/intermediates/ndkBuild/debug/obj/local/armeabi/objs-debug/native-lib/src/main/cp/stringdep.o'. Stop.
这看起来像你上面描述的错误。 Android.mk没有find你的SerialPort.c,所以我猜想SerialPort.c存放Android.mk的path是不正确的。 请记住,存储在Android.mk中的path是相对于Android.mk文件本身而不是根目录。
对于本地开发,你应该有main / jni文件夹,你应该把你的库和本地源代码放在里面,并在这个文件夹中构build它们。 在创build两个文件Android.mk和Application.mk之前, Android.mk用于构build本机库(模块),添加标志等。您可以在Android.mk中构build静态和共享库。 当您构buildC源代码时,它会创build静态库(.a)。 但是这些库不适合在Java方面使用。 您只能使用它们来创build共享库(.so)。 为此,您应该构buildC ++源代码,如果需要,可以将静态库添加到此源代码中。
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) ifneq (,$(filter $(TARGET_ARCH_ABI), armeabi-v7a x86 arm64-v8a x86_64)) LOCAL_MODULE := myLibrary LOCAL_SHARED_LIBRARIES := cpufeatures opencv_imgproc opencv_core LOCAL_C_INCLUDES := $(LOCAL_PATH)/c-files LOCAL_SRC_FILES := $(LOCAL_PATH)/myJni.cpp include $(BUILD_SHARED_LIBRARY)
—第一行返回main / jnipath。
—第二行清除所有旧的LOCAL _ ***variables。
—第三行为每个拱门build立模块,在那里宣布。
—第四行显示模块名称,当你build立它时,NDK会自动为它添加lib和.so扩展名(libmyLibrary.so)。
—第五行添加了其他共享库,您需要在本地来源中使用它们的源代码。
—第6行将C文件添加到您的模块。
—第7行显示您尝试构build的C ++源代码。
—第八行是build筑指挥。
在Application.mk中,您可以发布类似于您的项目的发布模式或debugging模式的命令。 而且你应该在这个文件中给arch。 例如APP_ABI := armeabi-v7a x86 arm64-v8a x86_64等
当你尝试构build库并在java端使用它们时,你应该做一些操作。
1.在项目文件夹的local.properties文件中检查你的ndkpath。 它显示了用于构buildmakefile的ndk-bundlepath。
ndk.dir=/Users/../Library/Android/sdk/ndk-bundle
2.检查gradle文件中的脚本。 这个脚本显示了共享库的位置:
sourceSets.main { jni.srcDirs = [] jniLibs.srcDir 'src/main/libs' }
3.并显示你的makefilepath到gradle。
externalNativeBuild { ndkBuild { path 'src/main/jni/Android.mk' } }
我想我的答案会帮助你理解一些细节。 另外,你也可以看看这些答案。
调用本地方法: input !
为了链接共享库: input !
从我的其他答案复制答案: input !