Android studio1.5.1 NDK配置开发

Posted tezlikai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android studio1.5.1 NDK配置开发相关的知识,希望对你有一定的参考价值。

注意:因为使用的工具和SDK版本不同,过程可能就不同,我把我试验过的几种情况都会说下。

一、工具和SDK版本:android studio1.51, SDK版本:23 (最新的6.0)

二、工具和SDK版本:Android studio1.51, SDK版本:21 


在这两种情况之前你必须做好一件事:安装NDK。过程如下:

在setting 中appearance -> Android SDK -> SDK Tools -> Android NDk 打钩,然后点击apply -> OK. 如下图:

技术分享


自动安装好DN卡之后,会在 local.properties 中有显示:如下图

技术分享


到此ND就安装完成了,那么接下来就是关键时刻了,先来看看情况一的具体过程:

1.  新建一个工程,就是一个简单的空白工程,功能也没有

2.  定义native 接口 和 加载即将生成的库。就几行代码,代码如下:


  1. package zhanghuan.cn.jnitest1;  
  2.   
  3. import android.support.v7.app.AppCompatActivity;  
  4. import android.os.Bundle;  
  5. import android.widget.TextView;  
  6.   
  7. public class MainActivity extends AppCompatActivity {  
  8.     static {  
  9.         System.loadLibrary("JniTest");  
  10.     }  
  11.   
  12.     public native String getStringFromNative();  
  13.   
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_main);  
  18.   
  19.         TextView textView = (TextView)findViewById(R.id.text);  
  20.         textView.setText(getStringFromNative());  // 调用接口  
  21.     }  
  22. }  

3. 写好接口之后接下来就是关键了,点击 Build -> Make Project, 如下图:

技术分享

然后在底部的状态栏Messages 中查看Build的情况,必须是0错误才行,如下图:

技术分享

4. Build 成功之后,就在Terminal 命令行中开始生成.h 文件

命令为:


  1. javah -d jni -classpath D:\tools\android-sdk\platforms\android-23\android.jar;D:\MyProject\AndroidStudio\JniTest1\app\src\main\java zhanghuan.cn.jnitest1.MainActivity  

就是这一步卡了我好久,之前找的教程每个的命令都是这样的:


  1. javah -d jni -classpath D:\tools\android-sdk\platforms\android.jar;..\..\build\intermediates\classes\debug zhanghuan.cn.jnitest1.MainActivity  

结果报错  “找不到android.support.v7.app.AppCompatActivity的类文件” 如下图:

技术分享


怎么试都不成功,最后发现除非不用V7特性,不继承AppCompatActivity 类,继承成普通的Activity就没事,这其中的差异我在后面会说的。但是我想如果在AppCompatActivity不应该不行的,虽然这是新特性,但它肯定能包容以前的。既然在debug 这中找不到,那我就直接在main 中指定类文件,不在debug中找了,结果让我发现居然成功了!当时心里呼了好长的一口气。成功的命令就是上面的第一个命令,直接指向类文件,然后生成了.h 文件,但是这个.h 文件和用debug 中的类文件生成的.h 文件是有区别的,这个区别待会在后面把.h 文件一对比就知道了。

回归正题,命令成功之后,在main 目录下回生成jni目录,然后还有一个.h 文件:如下图:

技术分享


我贴下.h 文件的代码:


  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>  
  3. /* Header for class zhanghuan_cn_jnitest1_MainActivity */  
  4.   
  5. #ifndef _Included_zhanghuan_cn_jnitest1_MainActivity  
  6. #define _Included_zhanghuan_cn_jnitest1_MainActivity  
  7. #ifdef __cplusplus  
  8. extern "C" {  
  9. #endif  
  10. /* 
  11.  * Class:     zhanghuan_cn_jnitest1_MainActivity 
  12.  * Method:    getStringFromNative 
  13.  * Signature: ()Ljava/lang/String; 
  14.  */  
  15. JNIEXPORT jstring JNICALL Java_zhanghuan_cn_jnitest1_MainActivity_getStringFromNative  
  16.   (JNIEnv *, jobject);  
  17.   
  18. #ifdef __cplusplus  
  19. }  
  20. #endif  
  21. #endif  
5. 复制.h 文件放在相同的目录下,改个名称(名字任意)为my.c , 代码如下:

  1. #include "zhanghuan_cn_jnitest1_MainActivity.h"  
  2.   
  3. JNIEXPORT jstring JNICALL Java_zhanghuan_cn_jnitest1_MainActivity_getStringFromNative  
  4.   (JNIEnv * env, jobject job) {  
  5.   return (*env)->NewStringUTF(env, "Hello form JNI!");  
  6. }  

但是这时你会发现有错误,NDK support is an experimental feature and all use cases are not yet supported, 如下图:

技术分享

解决方法是在 gradle.properties 文件中加入一句代码: 


  1. android.useDeprecatedNdk=true  


6. 在app 中的build.gradle 文件的defaultConfig 中加入NDK配置,指定生成的so文件名和适配的arm 类型. 加入代码:

  1. ndk{  
  2.            moduleName "JniTest"  
  3.            abiFilters "armeabi""armeabi-v7a""x86"  
  4.        }  
我的build.gradle 文件代码如下:

  1. apply plugin: ‘com.android.application‘  
  2.   
  3. android {  
  4.     compileSdkVersion 23  
  5.     buildToolsVersion "23.0.2"  
  6.   
  7.     defaultConfig {  
  8.         applicationId "zhanghuan.cn.jnitest1"  
  9.         minSdkVersion 11  
  10.         targetSdkVersion 23  
  11.         versionCode 1  
  12.         versionName "1.0"  
  13.   
  14.         ndk{  
  15.             moduleName "JniTest"  
  16.             abiFilters "armeabi""armeabi-v7a""x86"  
  17.         }  
  18.     }  
  19.     buildTypes {  
  20.         release {  
  21.             minifyEnabled false  
  22.             proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘  
  23.         }  
  24.     }  
  25. }  
  26.   
  27. dependencies {  
  28.     compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])  
  29.     testCompile ‘junit:junit:4.12‘  
  30.     compile ‘com.android.support:appcompat-v7:23.2.1‘  
  31. }  

到此,基本步骤就全部完成了,然后就直接运行一下,看下效果,效果图如下:

技术分享


成功完成!如果有兴趣可以看下下面的第二种情况。


好了,接下来我们就看看第二种情况:不使用V7。

1. 前面的几步步骤和第一种情况是一样的,到第4步的命令行开始有重要的差别, 我就直接跳到命令行那步了,命令如下:


  1. javah -d jni -classpath D:\tools\android-sdk\platforms\android-21\android.jar;D:\MyProject\AndroidStudio\JinTest\app\build\intermediates\classes\debug zhanghuan.cn.jintest.MainActivity  

注意如果出错要写绝对的地址,网上的教程都是什么”..\..\buidl\...“这种写法,但是我一次都没成功,折腾了很久都没成功,如果你成功了就请告诉我。

最后生成的.h 文件代码如下:


  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>  
  3. /* Header for class zhanghuan_cn_jintest_MainActivity */  
  4.   
  5. #ifndef _Included_zhanghuan_cn_jintest_MainActivity  
  6. #define _Included_zhanghuan_cn_jintest_MainActivity  
  7. #ifdef __cplusplus  
  8. extern "C" {  
  9. #endif  
  10. #undef zhanghuan_cn_jintest_MainActivity_BIND_ABOVE_CLIENT  
  11. #define zhanghuan_cn_jintest_MainActivity_BIND_ABOVE_CLIENT 8L  
  12. #undef zhanghuan_cn_jintest_MainActivity_BIND_ADJUST_WITH_ACTIVITY  
  13. #define zhanghuan_cn_jintest_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L  
  14. #undef zhanghuan_cn_jintest_MainActivity_BIND_ALLOW_OOM_MANAGEMENT  
  15. #define zhanghuan_cn_jintest_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L  
  16. #undef zhanghuan_cn_jintest_MainActivity_BIND_AUTO_CREATE  
  17. #define zhanghuan_cn_jintest_MainActivity_BIND_AUTO_CREATE 1L  
  18. #undef zhanghuan_cn_jintest_MainActivity_BIND_DEBUG_UNBIND  
  19. #define zhanghuan_cn_jintest_MainActivity_BIND_DEBUG_UNBIND 2L  
  20. #undef zhanghuan_cn_jintest_MainActivity_BIND_IMPORTANT  
  21. #define zhanghuan_cn_jintest_MainActivity_BIND_IMPORTANT 64L  
  22. #undef zhanghuan_cn_jintest_MainActivity_BIND_NOT_FOREGROUND  
  23. #define zhanghuan_cn_jintest_MainActivity_BIND_NOT_FOREGROUND 4L  
  24. #undef zhanghuan_cn_jintest_MainActivity_BIND_WAIVE_PRIORITY  
  25. #define zhanghuan_cn_jintest_MainActivity_BIND_WAIVE_PRIORITY 32L  
  26. #undef zhanghuan_cn_jintest_MainActivity_CONTEXT_IGNORE_SECURITY  
  27. #define zhanghuan_cn_jintest_MainActivity_CONTEXT_IGNORE_SECURITY 2L  
  28. #undef zhanghuan_cn_jintest_MainActivity_CONTEXT_INCLUDE_CODE  
  29. #define zhanghuan_cn_jintest_MainActivity_CONTEXT_INCLUDE_CODE 1L  
  30. #undef zhanghuan_cn_jintest_MainActivity_CONTEXT_RESTRICTED  
  31. #define zhanghuan_cn_jintest_MainActivity_CONTEXT_RESTRICTED 4L  
  32. #undef zhanghuan_cn_jintest_MainActivity_MODE_APPEND  
  33. #define zhanghuan_cn_jintest_MainActivity_MODE_APPEND 32768L  
  34. #undef zhanghuan_cn_jintest_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING  
  35. #define zhanghuan_cn_jintest_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L  
  36. #undef zhanghuan_cn_jintest_MainActivity_MODE_MULTI_PROCESS  
  37. #define zhanghuan_cn_jintest_MainActivity_MODE_MULTI_PROCESS 4L  
  38. #undef zhanghuan_cn_jintest_MainActivity_MODE_PRIVATE  
  39. #define zhanghuan_cn_jintest_MainActivity_MODE_PRIVATE 0L  
  40. #undef zhanghuan_cn_jintest_MainActivity_MODE_WORLD_READABLE  
  41. #define zhanghuan_cn_jintest_MainActivity_MODE_WORLD_READABLE 1L  
  42. #undef zhanghuan_cn_jintest_MainActivity_MODE_WORLD_WRITEABLE  
  43. #define zhanghuan_cn_jintest_MainActivity_MODE_WORLD_WRITEABLE 2L  
  44. #undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_DIALER  
  45. #define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_DIALER 1L  
  46. #undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_DISABLE  
  47. #define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_DISABLE 0L  
  48. #undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL  
  49. #define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L  
  50. #undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL  
  51. #define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L  
  52. #undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SHORTCUT  
  53. #define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SHORTCUT 2L  
  54. #undef zhanghuan_cn_jintest_MainActivity_RESULT_CANCELED  
  55. #define zhanghuan_cn_jintest_MainActivity_RESULT_CANCELED 0L  
  56. #undef zhanghuan_cn_jintest_MainActivity_RESULT_FIRST_USER  
  57. #define zhanghuan_cn_jintest_MainActivity_RESULT_FIRST_USER 1L  
  58. #undef zhanghuan_cn_jintest_MainActivity_RESULT_OK  
  59. #define zhanghuan_cn_jintest_MainActivity_RESULT_OK -1L  
  60. /* 
  61.  * Class:     zhanghuan_cn_jintest_MainActivity 
  62.  * Method:    getStringFromNative 
  63.  * Signature: ()Ljava/lang/String; 
  64.  */  
  65. JNIEXPORT jstring JNICALL Java_zhanghuan_cn_jintest_MainActivity_getStringFromNative  
  66.   (JNIEnv *, jobject);  
  67.   
  68. #ifdef __cplusplus  
  69. }  
  70. #endif  
  71. #endif  


是不是发现和第一种情况生成的.h 文件不同,多了很多的东西。不过这些东西好像然并卵,如果你知道其中的区别还请留言告诉我,非常感谢。

当然了,你还可以用第一种情况中的命令,也是OK的,同时不加上-classpath 和 android.jar,只指定要编译的类文件和.h文件目录就可以,如下:

  1. javah -d jni D:\MyProject\AndroidStudio\JinTest\app\build\intermediates\classes\debug zhanghuan.cn.jintest.MainActivity  

-d jni 是指定.h 生成后放的位置,不要自己建也是可以的。


最后生成的.so 文件在 app\build\intermediates\ndk\debug\lib 下,如下图:

技术分享


到此,全部的情况都已介绍完毕,当然了,如果你在做的时候有问题的话欢迎留言,我们大家一起讨论交流。



































以上是关于Android studio1.5.1 NDK配置开发的主要内容,如果未能解决你的问题,请参考以下文章

mac版androidstudio怎么配置ndk

android studio2.2 配置NDK

一定能成功的Android NDK环境配置教程

android studio ndk配置和ndk开发

android -------- Eclipse下的NDK配置环境

Ubuntu下配置Android NDK开发环境