关闭

AS2.2使用CMake方式进行JNI/NDK开发

标签: androidcmakendkjni
6536人阅读 评论(14) 收藏 举报
分类:

之前写过一篇比较水的文章Android手机控制电脑撸出HelloWorld
里面用到了JNI/NDK技术。

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

JNI(Java Native Interface)是java与C/C++进行通信的一种技术,使用JNI技术,可以java调用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. 对于include的头文件,或者库,也可以直接的进入
  4. 不需要配置命令行操作,手动的生成头文件,不需要配置android.useDeprecatedNdk=true 属性

下载

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

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

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

创建项目

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

然后一路 Next,直到 Finish 为止即可。

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

app/build.gradle也有所不同

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

externalNativeBuild {
     cmake {
         cppFlags "-std=c++11"
     }
 }

来看一下,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} )

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();
}

上面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());
}

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

运行项目

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

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

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

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

如果想验证一下apk是否有so文件,我们可以使用 APK Analyzer查看。
选择 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/main/jniLibs目录下。


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

手动添加native方法

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

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

这里写图片描述

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

参考之前的方法,照着葫芦画瓢,把错误先修复下。

修改MainActivity代码,调用我们写的native方法。

@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方法
}

编译运行当前程序。
运行结果:
这里写图片描述

可以看到我们成功调用了我们自己创建的native方法。


更多精彩请关注微信公众账号likeDev
这里写图片描述

2
0
查看评论

NDK-JNI实战教程(一) 在Android Studio运行第一个NDK程序

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!NDK开发,其实是为了项目需要调用底层的一些C/C++的一些东西;另外就是为了效率更加高些。如果你在Eclipse+ADT下开发过NDK就能体会到要么是配置NDK还要下...
  • yanbober
  • yanbober
  • 2015-04-27 13:23
  • 89299

AS jni调用入门(附图)

如题AS调用jni示例: 一、AS环境配置 1、初始步骤:本人开发环境为AS2.1.1 2、下载NDK,SDK没有下载的小伙伴就自行解决吧(没有NDK的小伙伴在红框的位置会有下载地址,可自行下载) 3、如果没有真机的小伙伴可以下载Genymotion模拟器,安装流程网上大把,有真机的可以忽略。 ...
  • why7788521521
  • why7788521521
  • 2016-05-30 13:20
  • 2756

Android Studio下JNI编程(引入外部或AS自行编译so文件)

1. 引用外部so文件 已验证过的引用外部so文件主要有三种方式: 1.1  main目录下创建jniLibs目录,so文件按平台存放于子目录下(最简单方式) 只需在app/src/main目录下创建jniLibs目录,然后将so文件按平台存放于对应子目录下即可。 1.2 将jni...
  • huangximin1990
  • huangximin1990
  • 2015-12-31 14:21
  • 5426

CMakeList配置之编译多个.cpp文件

上次提到AndroidStudio2.2进行NDK开发超方便的配置方式,不用进行Android.mk 配置,也不用进行Application.mk配置,只要配置CMakeList即可。那么问题来了,通过该方式生成的配置文件默认是只native-lib.cpp一个cpp文件的,那么怎么配置编译多个.c...
  • u011028777
  • u011028777
  • 2016-12-01 18:58
  • 4606

使用Android Studio 3.0 (>=2.2)和Cmake (CMakeLists)让OpenCV 3.4 飞起来

Github项目地址 如果懒得自己配,可以直接下载,包括使用Cmake作为工具的 OpenCV 3.4 for Android(支持Java 和 NDK C++,不需要额外配置,不需要OpenCV Manager),提供一个简单的相机Preview demo (注意,只包含armeabi-v7a,...
  • Martin20150405
  • Martin20150405
  • 2016-11-22 13:23
  • 8429

最新AS中如何使用NDK?

在AS更新到1.3之后移除了NDK的编译配置,所以当我们在更新到2.2之后时,如何配置呢?其实,在AS中一切都是那么的简单,接下来我用截图一步步给大家介绍: 1.下载NDK插件: 或者: 2.当下载完成后倒入: 3.创建最新集成ndk的项目: 创建完成后,项目中会自动生成cpp源文件、...
  • qq_21983189
  • qq_21983189
  • 2017-01-09 18:39
  • 1826

Android NDK系列(二)-AS使用CmakeLists生成so文件

接着上个文章,继续看AS能怎么生成so文件。 Android NDK系列(一)-AS使用javah生成so文件 :http://blog.csdn.net/sw5131899/article/details/77183352这个就简单多了,直接创建就行了。1、创建一个项目工程我之前Cmake没有,...
  • sw5131899
  • sw5131899
  • 2017-08-15 17:24
  • 624

AS2.2使用CMake方式进行JNI/NDK开发

之前写过一篇比较水的文章Android手机控制电脑撸出HelloWorld  里面用到了JNI/NDK技术。 这篇文章给大家介绍下JNI/NDK开发。采用的是Android Studio2.2开发环境,使用CMake方式进行开发。 JNI(Java N...
  • HelloMoney_
  • HelloMoney_
  • 2016-11-15 19:14
  • 1586

Android NDK开发(一) 使用CMake构建工具进行NDK开发

2018年的第一篇文章,主要讲解了JNI、NDK的一些概念以及在AS 3.0环境下如何使用CMake构建工具来进行NDK开发。 1.了解一些概念 JNI(Java Native Interface): Java原生接口,是Java和其他原生代码语言(例如 C 和 C++)通信的桥梁。 ...
  • kong_gu_you_lan
  • kong_gu_you_lan
  • 2018-01-18 09:07
  • 224

android NDK——搭建Android Studio的NDK环境

我接触jni的时候正在用android studio,所以我记录一下在as上部署ndk环境的步骤。首先先看一下大概步骤: 1,下载ndk 2,配置环境变量 3,配置as属性 4,java测试代码 5,创建.h的头文件 6,创建.c的测试c代码 7,生成so文件 8,测试ndk环境ok...
  • yehui928186846
  • yehui928186846
  • 2016-10-11 15:18
  • 8021
    个人资料
    • 访问:224106次
    • 积分:2640
    • 等级:
    • 排名:第16333名
    • 原创:74篇
    • 转载:1篇
    • 译文:0篇
    • 评论:238条
    关于我
    我的新书
    《爱上Android》已经出版
    本书绝不中庸,全是实用技术

    购买地址

    京东 天猫
    博客专栏
    最新评论