1、在eclipse上开发ndk项目时一般都是在项目里新建jni目录,通过编写Android.mk和Application.mk编译生成so库,然后放到libs目录下就可以使用,下面来看下,在AndroidStudio怎么采用这种方式生成so。
2、利用AndroidStudio配置几个需要用到的快捷命令,javah、ndk-build、ndk-build clean,具体作用如下:
Program:$JDKPath$\bin\javah.exe
Parameters:-classpath . -jni -d $ModuleFileDir$\src\main\jni $FileClass$
Working directory:$ModuleFileDir$\src\main\java
\\ndk路径
Program:D:\adt-bundle-windows-x86_64-20140702\android-ndk-r15c\ndk-build.cmd
Parameters:
Working directory:$ProjectFileDir$\app\src\main\
\\ndk路径
Program:D:\adt-bundle-windows-x86_64-20140702\android-ndk-r15c\ndk-build.cmd
Parameters:clean
Working directory:$ProjectFileDir$\app\src\main\
3、快捷命令配置好后,就可以开始了,选中需要生成jni头文件的java类,右键——>External Tool——>javah
会自动新建jni目录,并生成对应的jni头文件
public class NdkTest {
static {
System.loadLibrary("test_ndk");
}
public native String getString();
}
通过上面方式生成的头文件“com_jason_jni_demo2_NdkTest.h”
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_jason_jni_demo2_NdkTest */
#ifndef _Included_com_jason_jni_demo2_NdkTest
#define _Included_com_jason_jni_demo2_NdkTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jason_jni_demo2_NdkTest
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jason_jni_demo2_NdkTest_getString
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
编写头文件对应的NdkTest.c文件实现getString方法
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_jason_jni_demo2_NdkTest */
#ifndef _Included_com_jason_jni_demo2_NdkTest
#define _Included_com_jason_jni_demo2_NdkTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jason_jni_demo2_NdkTest
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jason_jni_demo2_NdkTest_getString
(JNIEnv * env, jclass clazz){
char * hello = "Hello World JNI2";
return (*env)->NewStringUTF(env,hello);
}
#ifdef __cplusplus
}
#endif
#endif
3、文件编写好后,就剩下Android.mk和Application.mk了,可根据自己情况编写,下面提供一个简单的demo
Android.mk具体内容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test_ndk
LOCAL_SRC_FILES := NdkTest.c
include $(BUILD_SHARED_LIBRARY)
Application.mk具体内容:
APP_MODULES := test_ndk
APP_ABI := all
4、万事俱备,只差编译了,这时配置的ndk-build命令又派上用场了,选中jni目录右键——>External Tool——>ndk-build
执行完这个命令后,会在jni同级目录生成libs目录和对应的so库,这时候就可以像之前一样使用了,但需要注意的是AndroidStudio 默认指定是加载jniLibs下的so,所以需要把libs目录改为jniLibs或者
在build.gradle里指定so的目录
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs']
}
}
另外还有个问题需要注意,如果是在AndroidStudio里直接这样编译apk会出现编译出错,如下:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugNdk'.
> Error: Your project contains C++ files but it is not using a supported native build system.
Consider using CMake or ndk-build integration with the stable Android Gradle plugin:
https://developer.android.com/studio/projects/add-native-code.html
or use the experimental plugin:
https://developer.android.com/studio/build/experimental-plugin.html.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
这是因为如果’src/main/jni’存在的话,AndroidStudio会采用自带的方式去编译生成so库,此时可以在build.gralde添加如下代码修复此问题:
defaultConfig {
applicationId "com.jason.jni.demo2"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] jni目录存在AndroidStudio会采用自身方式生成so库,需要配置这个,不然编译项目时候会出现上面的错误
}
}
}
源码下载地址