版权声明:本文为HaiyuKing原创文章,转载请注明出处!

概述

Android Studio使用ndk的简单步骤。

NDK环境搭建

下载NDK

下载链接:https://developer.android.com/ndk/downloads/index.html

PS:需要翻墙,建议下载r9+的版本。

国内下载地址:

http://www.wanandroid.com/tools/ide#NDK

解压 NDK包【建议在未打开Android Studio的情况下】

注:解压路径不要出现空格和中文。

建议:将文件解压到SDK目录里,并命名为ndk-bundle。好处:启动Android Studio时,Android Studio会自动检查它并直接添加到ndk.dir中,那么在使用时,就不用配置Android Studio与NDK的关联【解压的时候需要直接解压到sdk安装目录/ndk-bundle目录中才可以实现自动关联,否则需要手动关联】

因为我个人觉得不是每一个项目都需要用到ndk,所以就采用了手动关联的方式。

自动关联:sdk安装目录/ndk-bundle

手动关联:其他目录

下载安装Cmake

我是通过新建一个项目,根据Android Studio的提示信息进行安装的。其实也可以跳过新建项目的步骤,直接安装SDK Manager中安装。具体操作步骤见下文。

新建项目

新建项目

勾选Include C++ support

Next

Next

Next

选择C++标准,一般选择默认即可

手动关联NDK

对于解压ndk未解压到自动关联的目录(sdk安装目录/ndk-bundle)的情况,新建项目后会出现下面的提示信息,解决方案就是手动关联ndk。

对于解压ndk到自动关联的目录(sdk安装目录/ndk-bundle)的情况,可以跳过。因为不会出现下面的提示信息。如果万一出现了的话,那么就手动关联ndk即可。

File——Project Structure...

选择ndk路径

查看项目根目录的local.properties文件,会发现多了一行代码:

添加对旧版本的NDK支持

在工程中gradle.properties中添加以下代码:android.useDeprecatedNdk=true

下载安装Cmake

第一次运行会报错,原因是未安装Cmake。

打开SDK Manager

方式一

方式二:File——Settings...

安装cmake

运行

新建的项目含有一个cpp文件,可以看下效果:

将指定的.h和.cpp文件编译成so文件

首先修改生成的so文件的名称

打开CMakeLists.txt

最开始的:

  1. # For more information about using CMake with Android Studio, read the
  2. # documentation: https://d.android.com/studio/projects/add-native-code.html
  3.  
  4. # Sets the minimum version of CMake required to build the native library.
  5.  
  6. cmake_minimum_required(VERSION 3.4.1)
  7.  
  8. # Creates and names a library, sets it as either STATIC
  9. # or SHARED, and provides the relative paths to its source code.
  10. # You can define multiple libraries, and CMake builds them for you.
  11. # Gradle automatically packages shared libraries with your APK.
  12.  
  13. add_library( # Sets the name of the library.
  14. native-lib
  15.  
  16. # Sets the library as a shared library.
  17. SHARED
  18.  
  19. # Provides a relative path to your source file(s).
  20. src/main/cpp/native-lib.cpp )
  21.  
  22. # Searches for a specified prebuilt library and stores the path as a
  23. # variable. Because CMake includes system libraries in the search path by
  24. # default, you only need to specify the name of the public NDK library
  25. # you want to add. CMake verifies that the library exists before
  26. # completing its build.
  27.  
  28. find_library( # Sets the name of the path variable.
  29. log-lib
  30.  
  31. # Specifies the name of the NDK library that
  32. # you want CMake to locate.
  33. log )
  34.  
  35. # Specifies libraries CMake should link to your target library. You
  36. # can link multiple libraries, such as libraries you define in this
  37. # build script, prebuilt third-party libraries, or system libraries.
  38.  
  39. target_link_libraries( # Specifies the target library.
  40. native-lib
  41.  
  42. # Links the target library to the log library
  43. # included in the NDK.
  44. ${log-lib} )

修改后的:

  1. # For more information about using CMake with Android Studio, read the
  2. # documentation: https://d.android.com/studio/projects/add-native-code.html
  3.  
  4. # Sets the minimum version of CMake required to build the native library.
  5.  
  6. cmake_minimum_required(VERSION 3.4.1)
  7.  
  8. # Creates and names a library, sets it as either STATIC
  9. # or SHARED, and provides the relative paths to its source code.
  10. # You can define multiple libraries, and CMake builds them for you.
  11. # Gradle automatically packages shared libraries with your APK.
  12. # 编译出一个动态库 ndklib(名字随意命名),源文件只有 src/main/cpp/native-lib.cpp(如果含有多个的话,需要添加多行类似的代码)
  13. add_library( # Sets the name of the library.
  14. ndklib
  15.  
  16. # Sets the library as a shared library.
  17. SHARED
  18.  
  19. # Provides a relative path to your source file(s).
  20. src/main/cpp/native-lib.cpp )
  21.  
  22. # Searches for a specified prebuilt library and stores the path as a
  23. # variable. Because CMake includes system libraries in the search path by
  24. # default, you only need to specify the name of the public NDK library
  25. # you want to add. CMake verifies that the library exists before
  26. # completing its build.
  27.  
  28. find_library( # Sets the name of the path variable.
  29. log-lib
  30.  
  31. # Specifies the name of the NDK library that
  32. # you want CMake to locate.
  33. log )
  34.  
  35. # Specifies libraries CMake should link to your target library. You
  36. # can link multiple libraries, such as libraries you define in this
  37. # build script, prebuilt third-party libraries, or system libraries.
  38. # 找到预编译库 log_lib 并link到我们的动态库 ndklib(跟上面的保持一致)中
  39. target_link_libraries( # Specifies the target library.
  40. ndklib
  41.  
  42. # Links the target library to the log library
  43. # included in the NDK.
  44. ${log-lib} )

这样命名的话生成的so文件如下(前缀自动有个lib):

新建一个类文件LibNDKDemo.java(名字随意),并且引用我们新建的so库

添加以下代码:

  1. // Used to load the 'native-lib' library on application startup.
  2. static {
  3. System.loadLibrary("ndklib");
  4. }
  5.  
  6. /**
  7. * A native method that is implemented by the 'native-lib' native library,
  8. * which is packaged with this application.
  9. */
  10. public static native String stringFromJNI();

一般会有红色报错,不过不用着急。

鼠标定位到stringFromJNI方法那里,然后点击Alt+Enter,选择第一个AS会自动帮我们生成实现:

自动跳转到native-lib.cpp文件

将returnValue修改成真实的数据,并删除旧数据(上方黑色边框标记的代码),修改后的代码如下:

  1. #include <jni.h>
  2. #include <string>
  3.  
  4. extern "C"
  5. JNIEXPORT jstring JNICALL
  6. Java_com_why_project_ndkdemo_LibNDKDemo_stringFromJNI(JNIEnv *env, jobject instance) {
  7.  
  8. // TODO
  9. std::string hello = "Hello from C++";
  10. return env->NewStringUTF(hello.c_str());
  11. }

Build——Rebuild Project

此时,生成了debug模式下的so文件。

调用

将MainActivity.java下面的代码删除

修改后的代码:

  1. package com.why.project.ndkdemo;
  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.  
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_main);
  13.  
  14. TextView tv = (TextView) findViewById(R.id.sample_text);
  15. tv.setText(LibNDKDemo.stringFromJNI());
  16. }
  17. }

运行不报错,说明成功。

生成release版本的so文件

PS:(Debug版本和release版本,做个C++的都知道。debug版本是调试的使用的,里面包含很多的调试信息,文件体积也是比较大;release版本发布的时候使用的,会自动的去除掉里面的调试信息,文件体积比较小)。通过Gradle projects生成release版本:

生成的release版本so文件的位置:

将so文件结合module生成arr文件

其实上面的so文件就可以集成到项目中使用了,不过如果想要进一步封装so文件,比如指定cpu类型的so文件,或者还有其他代码需要配合调用等。

新建module(命名随意,包名需要跟so文件中的java文件包名一致)

module的包名必须跟so文件中的java文件(比如上面步骤中的LibNDKDemo.java)包名一致。

将需要用到的cpu类型的so文件(release版本)和java类文件拷贝到module中

一般不用将所有cpu类型的so文件拷贝到module中,根据实际项目情况。我这里将常用的cpu类型的so文件复制到module中。

将module生成arr文件

选择边上的Gradle——选择{module}目录下的 Tasks->build->assembleRelease方法

生成的arr文件位置:

将arr文件集成到其他项目中

注意:集成到的项目的编译、目标、最低SDK版本号应该大于等于生成arr文件的module中设置的版本号。

具体步骤,参考《【Android Studio安装部署系列】十七、Android studio引用第三方库、jar、so、arr文件

调用

运行效果:

遇到的问题

如果cpp目录下含有C文件,并且别的cpp文件引用这个C文件了,那么CMakeLists.txt文件需要添加以下配置

  1. # For more information about using CMake with Android Studio, read the
  2. # documentation: https://d.android.com/studio/projects/add-native-code.html
  3.  
  4. # Sets the minimum version of CMake required to build the native library.
  5.  
  6. cmake_minimum_required(VERSION 3.4.1)
  7.  
  8. add_library(aes-lib STATIC src/main/cpp/aes.c)
  9.  
  10. # Creates and names a library, sets it as either STATIC
  11. # or SHARED, and provides the relative paths to its source code.
  12. # You can define multiple libraries, and CMake builds them for you.
  13. # Gradle automatically packages shared libraries with your APK.
  14. # 编译出一个动态库 urlpath,源文件有 src/main/cpp/native-lib.cpp等
  15. add_library( # Sets the name of the library.
  16. urlpath
  17.  
  18. # Sets the library as a shared library.
  19. SHARED
  20.  
  21. # Provides a relative path to your source file(s).
  22. src/main/cpp/base64.cpp
  23. src/main/cpp/url_auth.cpp
  24. src/main/cpp/native-lib.cpp
  25. )
  26.  
  27. # Searches for a specified prebuilt library and stores the path as a
  28. # variable. Because CMake includes system libraries in the search path by
  29. # default, you only need to specify the name of the public NDK library
  30. # you want to add. CMake verifies that the library exists before
  31. # completing its build.
  32.  
  33. find_library( # Sets the name of the path variable.
  34. log-lib
  35.  
  36. # Specifies the name of the NDK library that
  37. # you want CMake to locate.
  38. log )
  39.  
  40. # Specifies libraries CMake should link to your target library. You
  41. # can link multiple libraries, such as libraries you define in this
  42. # build script, prebuilt third-party libraries, or system libraries.
  43. #找到预编译库 log_lib 并link到我们的动态库 urlauth中
  44. target_link_libraries( # Specifies the target library.
  45. urkpath
  46. aes-lib
  47. # Links the target library to the log library
  48. # included in the NDK.
  49. ${log-lib} )

否则会报错:提示没有找到C文件中的方法。

参考资料

详解Android studio ndk配置cmake开发native C

AndroidStudio报错: undefined reference to 'AndroidBitmap_getInfo'

Android Studio 下安卓 jni 开发错误 undefined reference to AndroidBitmap_getInfo

NDK SO 库开发与使用中的 ABI 构架选择

Android Studio2.2.3使用C++生成so文件

Android NDK开发扫盲及最新CMake的编译使用

Android 生成.so文件

关于Android so文件你所需要了解的

Android Studio配置CMake开发NDK

Android JNI作用及其详解

AndroidStudio官方指南:向您的项目添加 C 和 C++ 代码

Android Studio 开发JNI笔记--②

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

Android Studio 2.2+ NDK开发

Android Studio NDK编程-环境搭建及Hello!

NDK开发 从入门到放弃(七:Android Studio 2.2 CMAKE 高效NDK开发)

Android NDK开发之从环境搭建到Demo级十步流

Android Studio NDK环境配置及JNI使用方法

android studio 调用c/c++工程

android studio 编译C生成.so文件

.arr文件的生成与使用

android studio library生成jar包和aar的方法总结

android studio生成aar包并在其他工程引用aar包

Android jniLibs下目录详解(.so文件)

Android Studio生成so文件的几种方式

android中.aar文件与.jar文件的区别

jar文件和aar文件的区别

Android NDK是什么,为什么我们要用NDK?

Android Native crash日志分析

android 底层log分析 内存及backtrace tombstone/crash

使用新版Android Studio检测内存泄露和性能

C++中内存泄漏的几种情况

c语言内存泄露示例

C++内存泄露的检测(三)

使用LeakTracer检测android NDK C/C++代码中的memory leak

【Android Studio安装部署系列】二十五、Android studio使用NDK生成so文件和arr文件的更多相关文章

  1. 【Android Studio安装部署系列】十五、Android studio添加Assets目录

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio新建项目时是没有assets目录,需要自己手动创建. app右键——New——Folder——Asset ...

  2. 【Android Studio安装部署系列】十、Android studio打包发布apk安装包

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 使用Android studio发布apk安装包的操作步骤. 开始打包发布apk Build > Generate Signe ...

  3. 【Android Studio安装部署系列】十二、Android studio代码混淆

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 为什么需要代码混淆呢?原因很简单,你的apk很容易被反编译出来,你写的代码都会被看到,因此我们需要在编译过程中对代码进行一定程度的混 ...

  4. 【Android Studio安装部署系列】十九、Android studio使用SVN

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 在AndroidStudio中开发版本控制,除了Git就是SVN,和Eclipse不同,Android Studio没有提供单独的插 ...

  5. 【Android Studio安装部署系列】十六、Android studio在layout目录下新建子目录

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 一般用于分类显示不同模块的layout布局文件. 在res/layout文件夹下创建子目录 res/layout鼠标右键——New— ...

  6. 【Android Studio安装部署系列】十七、Android studio引用第三方库、jar、so、arr文件

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 在Android开发过程,经常需要用到第三方库以及jar.so.arr文件,那么如何引用到项目中呢?下面简单介绍下. 引用第三方库 ...

  7. 【Android Studio安装部署系列】四、Android SDK目录和作用分析

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android SDk Tool软件开发工具包(software development kit).被软件开发工程师用于为特定的软件 ...

  8. 【Android Studio安装部署系列】十八、Android studio更换APP应用图标

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio新建项目后会有一个默认图标,那么如何更换图标呢? 替换图标 这个方案不建议直接在已有项目上更换图标,建议 ...

  9. 【Android Studio安装部署系列】十四、Android studio移除工程和删除项目

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio删除工程.项目的操作步骤. 移除工程 主要用于从最近打开的项目列表中移除.硬盘中还是存在这个项目的. F ...

  10. 【Android Studio安装部署系列】三、Android Studio项目目录结构

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 简单介绍下Android studio新建项目的目录结构. 常用项目结构类型 在Android Studio中,提供了以下几种项目结 ...

随机推荐

  1. n级阶梯,每次走一步或两步,问最多有多少种走法 二叉树实现

    NodeTree类 public class NodeTree { private int num; private NodeTree left; private NodeTree right; pu ...

  2. 理解、学习与使用 Java 中的 Optional

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...

  3. 解锁 vmware esxi 6.7 并安装 mac os 10.13

    1.安装 esxi 6.7 2.下载 unlocker 2.1.1.zip 3.上传 unlocker 2.1.1.zip esxi的磁盘中 4.开启esxi的ssh登录 5.使用 ssh 登录 es ...

  4. Spring事务管理----事物回滚

    Spring的事务管理默认只对未检查异常(java.lang.RuntimeException及其子类)进行回滚,如果一个方法抛出Checked异常,Spring事务管理默认不进行回滚. 改变默认方式 ...

  5. Python 视频转字符画 - 进阶

    这篇文章是 视频转字符动画-Python-60行代码 的后续,如果感兴趣,请先看看它. 1. 速度优化 要是每次播放都要等个一分钟,也太痛苦了一点. 所以可以用 pickle 模块把 video_ch ...

  6. spss汉化详解

    今天写一下关于SPSS的汉化以及激活码 下载spss: 安装过程比较简单,主要就是激活码: 9DNCAF2O3QVDV7FBIO696OO6GWLNXZPPRYTPWF2PPX7C8T6Y24LMVV ...

  7. GT工具中用到的英文词解释

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 ...

  8. Mui Webview下来刷新上拉加载实现

    有些事情经历过之后才会发现,原来再次之前我是如此的啥,因为是第一次做,毫无头绪,有时会想假如有个一demo就好了,那么就不会花费这么多的无用功了.今天使用mui 的webview实现了一个H5页面的上 ...

  9. 【工具篇】Selenium 学习实践(一)环境搭建

    一.环境搭建 (1)初学者最佳环境: Python 2.7 + Selenium 2+ Firefox 46 (2)喜欢尝新的环境: Python 3.6 + Selenium 3+ Firefox ...

  10. SVM分类器实现实例

    我正在做一个关于SVM的小项目,在我执行验证SVM训练后的模型的时候,得到的report分数总是很高,无论是召回率(查全率).精准度.还是f1-score都很高: 图1 分类器分数report 但是, ...