【Android Studio安装部署系列】二十五、Android studio使用NDK生成so文件和arr文件
版权声明:本文为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
最开始的:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library.
native-lib # Sets the library as a shared library.
SHARED # Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp ) # Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build. find_library( # Sets the name of the path variable.
log-lib # Specifies the name of the NDK library that
# you want CMake to locate.
log ) # Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library.
native-lib # Links the target library to the log library
# included in the NDK.
${log-lib} )
修改后的:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
# 编译出一个动态库 ndklib(名字随意命名),源文件只有 src/main/cpp/native-lib.cpp(如果含有多个的话,需要添加多行类似的代码)
add_library( # Sets the name of the library.
ndklib # Sets the library as a shared library.
SHARED # Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp ) # Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build. find_library( # Sets the name of the path variable.
log-lib # Specifies the name of the NDK library that
# you want CMake to locate.
log ) # Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
# 找到预编译库 log_lib 并link到我们的动态库 ndklib(跟上面的保持一致)中
target_link_libraries( # Specifies the target library.
ndklib # Links the target library to the log library
# included in the NDK.
${log-lib} )
这样命名的话生成的so文件如下(前缀自动有个lib):

新建一个类文件LibNDKDemo.java(名字随意),并且引用我们新建的so库
添加以下代码:
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("ndklib");
} /**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public static native String stringFromJNI();
一般会有红色报错,不过不用着急。

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

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

将returnValue修改成真实的数据,并删除旧数据(上方黑色边框标记的代码),修改后的代码如下:
#include <jni.h>
#include <string> extern "C"
JNIEXPORT jstring JNICALL
Java_com_why_project_ndkdemo_LibNDKDemo_stringFromJNI(JNIEnv *env, jobject instance) { // TODO
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
Build——Rebuild Project

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

调用
将MainActivity.java下面的代码删除

修改后的代码:
package com.why.project.ndkdemo; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(LibNDKDemo.stringFromJNI());
}
}
运行不报错,说明成功。
生成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文件需要添加以下配置
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) add_library(aes-lib STATIC src/main/cpp/aes.c) # Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
# 编译出一个动态库 urlpath,源文件有 src/main/cpp/native-lib.cpp等
add_library( # Sets the name of the library.
urlpath # Sets the library as a shared library.
SHARED # Provides a relative path to your source file(s).
src/main/cpp/base64.cpp
src/main/cpp/url_auth.cpp
src/main/cpp/native-lib.cpp
) # Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build. find_library( # Sets the name of the path variable.
log-lib # Specifies the name of the NDK library that
# you want CMake to locate.
log ) # Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
#找到预编译库 log_lib 并link到我们的动态库 urlauth中
target_link_libraries( # Specifies the target library.
urkpath
aes-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
否则会报错:提示没有找到C文件中的方法。
参考资料
详解Android studio ndk配置cmake开发native C
AndroidStudio报错: undefined reference to 'AndroidBitmap_getInfo'
Android Studio 下安卓 jni 开发错误 undefined reference to AndroidBitmap_getInfo
Android Studio2.2.3使用C++生成so文件
AndroidStudio官方指南:向您的项目添加 C 和 C++ 代码
Android Studio NDK编程-环境搭建及Hello!
NDK开发 从入门到放弃(七:Android Studio 2.2 CMAKE 高效NDK开发)
Android Studio NDK环境配置及JNI使用方法
android studio library生成jar包和aar的方法总结
android studio生成aar包并在其他工程引用aar包
android 底层log分析 内存及backtrace tombstone/crash
使用LeakTracer检测android NDK C/C++代码中的memory leak
【Android Studio安装部署系列】二十五、Android studio使用NDK生成so文件和arr文件的更多相关文章
- 【Android Studio安装部署系列】十五、Android studio添加Assets目录
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio新建项目时是没有assets目录,需要自己手动创建. app右键——New——Folder——Asset ...
- 【Android Studio安装部署系列】十、Android studio打包发布apk安装包
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 使用Android studio发布apk安装包的操作步骤. 开始打包发布apk Build > Generate Signe ...
- 【Android Studio安装部署系列】十二、Android studio代码混淆
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 为什么需要代码混淆呢?原因很简单,你的apk很容易被反编译出来,你写的代码都会被看到,因此我们需要在编译过程中对代码进行一定程度的混 ...
- 【Android Studio安装部署系列】十九、Android studio使用SVN
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 在AndroidStudio中开发版本控制,除了Git就是SVN,和Eclipse不同,Android Studio没有提供单独的插 ...
- 【Android Studio安装部署系列】十六、Android studio在layout目录下新建子目录
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 一般用于分类显示不同模块的layout布局文件. 在res/layout文件夹下创建子目录 res/layout鼠标右键——New— ...
- 【Android Studio安装部署系列】十七、Android studio引用第三方库、jar、so、arr文件
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 在Android开发过程,经常需要用到第三方库以及jar.so.arr文件,那么如何引用到项目中呢?下面简单介绍下. 引用第三方库 ...
- 【Android Studio安装部署系列】四、Android SDK目录和作用分析
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android SDk Tool软件开发工具包(software development kit).被软件开发工程师用于为特定的软件 ...
- 【Android Studio安装部署系列】十八、Android studio更换APP应用图标
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio新建项目后会有一个默认图标,那么如何更换图标呢? 替换图标 这个方案不建议直接在已有项目上更换图标,建议 ...
- 【Android Studio安装部署系列】十四、Android studio移除工程和删除项目
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio删除工程.项目的操作步骤. 移除工程 主要用于从最近打开的项目列表中移除.硬盘中还是存在这个项目的. F ...
- 【Android Studio安装部署系列】三、Android Studio项目目录结构
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 简单介绍下Android studio新建项目的目录结构. 常用项目结构类型 在Android Studio中,提供了以下几种项目结 ...
随机推荐
- python之分析decode、encode、unicode编码转换
decode()方法使用注册编码的编解码器的字符串进行解码.它默认为默认的字符串编码.decode函数可以将一个普通字符串转换为unicode对象.decode是将普通字符串按照参数中的编码格式进行解 ...
- HTTP/HTTPS 学习笔记
超文本传输协议(HyperText Transfer Protocol) 伴随着计算机网络和浏览器的诞生,HTTP1.0也随之而来,处于计算机网络中的应用层,HTTP是建立在TCP协议之上的. HTT ...
- Java 读书笔记 (一) 基本知识
1. 基本概念 对象 对象是类的一个实例,有状态和行为. 例如,一条狗是一个对象,它的状态有:颜色.名字.品种:行为有: 摇尾.叫.吃等. 类 类是一个模板,它描述一类对象的行为和状态. 方法 方法就 ...
- 树莓派.设置无线网卡为AP工作模式(pi2和pi3)
树莓派2的设置办法: 1. 安装NetworkManager管理工具(可选),以支持nmcli命令 sudo apt-get install -y network-manager 2. 安装hosta ...
- 将函数声明为Static的作用
表示静态函数,它为所有类共有的.调用该函数直接使用类名加上修饰符,如:Windows win;Windows::W_SIZE();而不是:win.W_SIZE();静态函数只能处理静态数据成员,不能处 ...
- turtle文库 ——python
本文将会为您介绍关于python--turtle库函数,学会这个库函数,会有很多让你意想不到的事情发生哦! 我也也会为你们,简单的编写几个代码,让你们看一下turtle函数的魅力 Turtle库是Py ...
- 【机器学习基础】对 softmax 和 cross-entropy 求导
目录 符号定义 对 softmax 求导 对 cross-entropy 求导 对 softmax 和 cross-entropy 一起求导 References 在论文中看到对 softmax 和 ...
- 前端性能优化 —— 添加Expires头与Cache-control区别
要:添加Expires头能有效的利用浏览器的缓存能力来改善页面的性能,能在后续的页面中有效避免很多不必要的Http请求,WEB服务器使用Expires头来告诉Web客户端它可以使用一个组件的当前副本, ...
- Asp.Net Core&钉钉开发系列
阿里钉钉在商业领域的规模越来越大,基于钉钉办公的企业越来越多,将一个企业内现有用到的工具(如钉钉)能够更融入到他们的工作中,提高工作效率,那便需要开发者不断的学习.应用了,同时,个人也有一个预感,未来 ...
- Linux三剑客-grep || awk || sed
grep是一个强大的文本搜索工具 命令格式: grep [option] pattren file -a 将二进制文档以文本方式处理 -c 计算找到的符合行的次数 -i 忽略大小写 -n 顺便 ...