转自:http://blog.csdn.net/sodino/article/details/41946607
使用Android Sutdio创建一个新的工程后,接下来记录创建NDK工程的基本步骤。
本文将达到:
1. 创建NDK工程
2. 在JNI中输出Log语句
3. 指定编译的so库的abi版本
4. 解决在创建NDK工程中的问题
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 Projec t
这一步骤执行一下,验证工程中并无其它错误,并对工程进行了编译,生成了.class文件.
.class文件的生成路径是在 app_path/build/intermediates/classes/debug下的.如下图:
Step: 3.javah生成c头文件
点击"View->Tool Windows->Terminal",即在Studio中进行终端命令行工具.执行如下命令生成c语言头文件。
这里需要注意的是要进入
<Project>\app\src\main 的目录下执行javah命令,为的是生成的jni目录和java目录在同一级别下
javah -d jni -classpath ./java lab.sodino.jnitest.MainActivity
-d jni 头文件生成到jni文件夹(当前在<Project>\app\src\main目录下,所以.h所在的目录为<Project>\app\src\main\jni )
-classpath ./java 指定去当前路径下java下寻找包名指定的类
Step: 4.编辑c文件
在jni目录下创建main.c
在main.c文件中实现头文件中的方法,具体功能为直接return回一个String,并且使用android_log打印出相关日志。
代码如下:
#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 #ifndef _Included_lab_sodino_jnitest_MainActivity #define _Included_lab_sodino_jnitest_MainActivity #ifdef __cplusplus extern "C" { #endif 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
Step: 5.配置NDK
这一步包括两个动作:
1.指明ndk路径
2. 修改build.gradle配置
工程中共有两个build.gradle配置文件,我们要修改的是在<Project>\app\build.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平台上会出现一个问题:(新版android Studio已经解决这个bug)
Error:Execution failed for task ':app:compileDebugNdk' . > com.android.ide.common.internal.LoggedErrorException: Failed to run command: D:\Mission\adt-bundle-windows\ndk-r10b\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android- 21 NDK_OUT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\lib APP_ABI=armeabi,armeabi-v7a,x86 Error Code: 2 Output: make.exe: *** No rule to make target `C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/JniTest/C_\Users\sodinochen\AndroidstudioProjects\JniTest2\app\src\main\jni', needed by `C:\Users\sodinochen\AndroidstudioProjects\JniTest2\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/JniTest/C_\Users\sodinochen\AndroidstudioProjects\JniTest2\app\src\main\jni\main.o' . Stop.
出现这个错误很莫名其妙..几番折腾下,找到一个视频出来了大概原因及解决方式:
在Windows下NDK一个bug,当仅仅编译一个文件时出现会出现此问题,解决方法就是
再往jni文件夹加入一个空util.c文件 即可。如下图:
编译出来的库文件被Studio输出到了下图的路径中
Step: 6.安装运行
界面:
查看Log打印: