android ndk cmake配置(转载)

这篇文章给大家介绍下JNI / NDK开发。采用的是Android Studio2.2开发环境,使用CMake方式进行开发。

JNI(Java Native Interface)是java与C / C ++进行通信的一种技术,使用JNI技术,可以调用C / C ++的函数对象等等,Android中的Framework层与Native层就是采用的JNI技术。

我们知道,Android系统是基于linux开发,采用的是linux内核,Android APP开发大部分也要求和系统打交道,只是Android FrameWork帮我们处理了和系统相关的操作,我们从Android系统的分成结构可以看出,Android FrameWork是通过JNI与底层的C / C ++库交互,例如:FreeType,OpenGL,SQLite,音视频等等。

 
如果我们程序也需要调用自己的C / C ++函数库,就必须用到JNI / NDK开发。

NDK配置(最新的CMake的方式)

Android Studio2.2版本已经完全支持ndk开发了。而且默认采用CMake方式。(传统方式不过多介绍了)

CMake的的优势

  1. 可以直接的在C / C ++代码中加入断点,进行调试
  2. 的java引用的C / C ++中的方法,可以直接CTRL +左键进入
  3. 对于包括的头文件,或者库,也可以直接的进入
  4. 不需要配置命令行操作,手动的生成头文件,配置不需要android.useDeprecatedNdk=true属性

下载

首先需要下载NDK,来到设置界面点击下载NDK 
这里写图片描述 

安装完NDK,还可以选择配置一些工具。 

  1. CMake:外部构建工具。如果你准备只使用ndk-build的话,可以不使用它。(Android Studio2.2默认采用CMake)
  2. LLDB:Android Studio上面调试本地代码的工具。

创建项目

Android Studio升级到2.2版本之后,在创建新的项目时,界面上多了一个包含C ++支持的选项,勾选它之后将会创建一个默认的C ++与JAVA混编的Demo程序。 

然后一路接下来,直到完成为止即可。 

上面图的这三个文件都是默认生成的NDK项目的一部分: 
1.externalNativeBuild文件夹:cmake编译好的文件,显示支持的各种硬件等信息。系统生成 
。2. cpp文件夹:存放C / C ++代码文件,native-lib.cpp文件是默认生成的,可更改。需要自己编写。3. 
CMakeLists.txt文件:CMake脚本配置的文件。需要自己配置编写。

应用程序/的build.gradle也有所不同 

如果你在创建工程选择C ++ 11的标准,则使用cppFlags“-std = c ++ 11”

externalNativeBuild {
     cmake {
         cppFlags "-std=c++11"
     }
 }
  • 1
  • 2
  • 3
  • 4

来看一下,的CMakeLists.txt文件中的具体配置

这个文件#开头的全是注释,里面不是注释的只有下面的内容。

cmake_minimum_required(VERSION 3.4.1) #指定cmake版本


add_library( #生成函数库的名字
             native-lib  
             SHARED  #生成动态函数看
             src/main/cpp/native-lib.cpp ) #依赖的cpp文件

find_library( #设置path变量的名称
              log-lib
              #指定要查询库的名字
              log ) #在ndk开发包中查询liblog.so函数库(默认省略lib和.so),路径赋值给log-lib

target_link_libraries( #目标库,和上面生成的函数库名字一至
                       native-lib
             #连接的库,根据log-lib变量对应liblog.so函数库
                       ${log-lib} )
  • 1
  • 2
  • 3
  • 4
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

java的代码

public class MainActivity extends AppCompatActivity {

    // 加载函数库
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**本地方法, 当前方法是通过C/C++代码实现*/
    public native String stringFromJNI();
}
  • 1
  • 2
  • 3
  • 4
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

上面java代码中的stringFromJNI()方法用native关键字修饰,这个方法是通过C / C ++代码实现的。

native-lib.cpp代码

#include <jni.h>  
#include <string>

extern "C"
jstring
Java_com_a520wcf_jniproject_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
  • 1
  • 2
  • 3
  • 4
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上面的C ++代码,定义的函数名是固定写法,Java_包名_类名_Java中方法名,通过这种命名方式就可以唯一对应到java中具体的方法,从而具体实现java中的native方法。

运行项目

修改完C / C ++代码需要点击“锤子”图标进行编译,然后运行项目。 

运行代码,就能看到效果,调用了C ++方法在界面上显示了Hello from C ++字符串。

如果你不是使用CMake而是使用传统方式进行开发,这时候就会使用了ndk -build来编译C / C ++文件为so文件。

那么,我们安装运行的APK中,有对应的使文件吗?

如果想验证一下apk是否有so文件,我们可以使用APK分析器查看。
选择Build> Analyze APK。

选择apk,并点击OK。
当前项目debug阶段的apk默认路径为app / build / outputs / apk / app-debug.apk

如下图,在APK Analyzer窗口中,选择lib / x86 /,可以看见libnative-lib.so。 

的.so文件是动态函数库,写好的C / C ++代码默认打包成函数库,就没法看到代码,只能使用了。

如果我们想在工程中使用其他人编译好的函数库,只需要根据不同的CPU架构把函数库在SRC /主/ jniLibs目录下。

 
在java的代码中也需要引入相应的函数库,编写一样的本地方法。

手动添加本地方法

上面我们主要介绍程序自动生成的代码,接下来我们自己动手写写。
我们也可以在MainActivity中写一个本地方法。

有红色警告,因为当前方法并没有找到对应的底层代码的实现。我们可以在报错的地方按下万能的快捷键ALT +回车。

这里写图片描述

选择第一项,就会自动生成对应的底层方法。

参考之前的方法,照着葫芦画瓢,把错误先修复下。
 
修改MainActivity代码,调用我们写的本地方法。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView tv = (TextView) findViewById(R.id.sample_text);
    tv.setText(stringFromJNI2());//调用新写的native方法
}
  • 1
  • 2
  • 3
  • 4
  • 6
  • 7
  • 8

。运行compile-当前程序
运行查询查询结果:
这里写图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值