使用Android Sutdio创建一个新的project后,接下来记录创建NDKproject的基本步骤。
本文将达到:
1. 创建NDKproject
2. 在JNI中输出Log语句
3. 指定编译的so库的abi版本号
4. 解决在创建NDKproject中的问题
Step: 1. 加入native接口
注意写好native接口和System.loadLibrary()就可以了。并无特别之处。
P.S:onCreate()中对R.id.txt运行setText()。所以这里须要对xml布局文件按正常的开发步骤进行改动就可以。
直接给出代码例如以下:
public class MainActivity extends Activity{ static { System.loadLibrary("JniTest"); } public native String getStringFromNative(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView txtView = (TextView) findViewById(R.id.txt); txtView.setText(getStringFromNative()); } }
Step: 2.运行Build->Make Project
这一步骤运行一下,验证project中并无其他错误,并对project进行了编译,生成了.class文件.
.class文件的生成路径是在 app_path/build/intermediates/classes/debug下的.例如以下图:
Step: 3.javah生成c头文件
点击"View->Tool Windows->Terminal",即在Studio中进行终端命令行工具.运行例如以下命令生成c语言头文件。
这里须要注意的是要进入 <Project>appsrcmain的文件夹下运行javah命令,为的是生成的 .h 文件相同是在<Project>appsrcmain路径下,能够在Studio的project结构中直接看到。
操作命令:
javah -d jni -classpath <SDK_android.jar>;<APP_classes> lab.sodino.jnitest.MainActivity
详细操作图例如以下:
javah -d jni -classpath c:UserssodinochenAppDataLocalAndroidsdkplatforms android-16android.jar;....uildintermediatesclassesdebug lab.sodino.jnitest.MainActivity
对于"主版本号51比50新,此编译器支持最新的主版本号"则是因为电脑上安装了两个版本号的jdk引起的,而当前使用的是旧的jdk。
把旧的jdk删除。并运行java version命令后显示当前jdk为最新的1.7时,则不会再有此提示了。例如以下图:
最后的生成结果:
Step: 4.编辑c文件
在main.c文件里实现头文件里的方法,详细功能为直接return回一个String。而且使用android_log打印出相关日志。
代码例如以下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> #include <android/log.h> #ifndef LOG_TAG #define LOG_TAG "ANDROID_LAB" #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #endif /* Header for class lab_sodino_jnitest_MainActivity */ #ifndef _Included_lab_sodino_jnitest_MainActivity #define _Included_lab_sodino_jnitest_MainActivity #ifdef __cplusplus extern "C" { #endif /* * Class: lab_sodino_jnitest_MainActivity * Method: getStringFromNative * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_lab_sodino_jnitest_MainActivity_getStringFromNative (JNIEnv * env, jobject jObj){ LOGE("log string from ndk."); return (*env)->NewStringUTF(env,"Hello From JNI!"); } #ifdef __cplusplus } #endif #endif
到这里后。我们再运行一个"Build->Make Project"。发现"Messages Gradle Build"会给出提演示样例如以下:
Error:Execution failed for task ':app:compileDebugNdk'. > NDK not configured. Download the NDK from http://developer.android.com/tools/sdk/ndk/.Then add ndk.dir=path/to/ndk in local.properties. (On Windows, make sure you escape backslashes, e.g. C:\ndk rather than C: dk)
这里提示了NDK未配置,而且须要在project中的local.properties文件里配置NDK路径。
好了,提示非常清楚了。那我们就进入下一步吧。
这一步包含两个动作:
1.指明ndk路径
2. 改动build.gradle配置
project中共同拥有两个build.gradle配置文件。我们要改动的是在<Project>appuild.gradle这个文件。为其在defaultConfig分支中添加上
ndk { moduleName "JniTest" ldLibs "log", "z", "m" abiFilters "armeabi", "armeabi-v7a", "x86" }
以上配置代码指定的so库名称为JniTest,链接时使用到的库。相应android.mk文件里的LOCAL_LDLIBS。及终于输出指定三种abi体系结构下的so库。
加入后例如以下图:
这时,再运行"Build->Rebuild Project",就能够编译出so文件了。
但在Window平台上会出现一个问题:
Error:Execution failed for task ':app:compileDebugNdk'. > com.android.ide.common.internal.LoggedErrorException: Failed to run command: D:Missionadt-bundle-windows dk-r10b dk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates dkdebugAndroid.mk APP_PLATFORM=android-21 NDK_OUT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates dkdebugobj NDK_LIBS_OUT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates dkdebuglib APP_ABI=armeabi,armeabi-v7a,x86 Error Code: 2 Output: make.exe: *** No rule to make target `C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates dkdebugobj/local/armeabi/objs/JniTest/C_UserssodinochenAndroidstudioProjectsJniTest2appsrcmainjni', needed by `C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates dkdebugobj/local/armeabi/objs/JniTest/C_UserssodinochenAndroidstudioProjectsJniTest2appsrcmainjnimain.o'. Stop.
出现这个错误非常莫名其妙..几番折腾下,找到一个视频出来了大概原因及解决方案:
出处见Youtube视频 02:50分開始:https://www.youtube.com/watch?
v=okLKfxfbz40#t=362
在Windows下NDK一个bug,当只编译一个文件时出现会出现此问题,解决方法就是再往jni文件夹加入一个空util.c文件就可以。例如以下图:
Step: 6.安装运行
界面:
查看Log打印: