我的Android NDK之旅(三),使用cmake来构建Jni

来源:互联网 发布:linux init3 编辑:程序博客网 时间:2024/06/06 11:38

转载请注明出处:(http://blog.csdn.net/qq_35071078/article/details/70544766)

使用cmake来构建jni


什么是cmake

使用Android Studio 2.2及更高版本 ,您可以使用NDK和CMake将C和C ++代码编译为本机库。 然后,Android Studio将您的图书馆打包到您的APK中,该版本是IDE的集成构建系统 。

如果您刚接触使用CMake与Android Studio,请到您的项目中添加C和C ++代码,以了解将本机源添加到项目的基础知识,创建CMake构建脚本,并将CMake项目添加为Gradle依赖项。 此页面提供了一些可用于自定义CMake构建的附加信息

具体用cmake构建jni可以去看谷歌官方参考

使用cmake需要什么

  • Android 原生开发工具包:就是ndk

  • CMake:一款外部构建工具,可以Gradle搭配使用来构建原生库,如果你只计划使用 ndk-build,则不需要此组件。

  • LLDB:一种调试程序,Android Studio 使用它来调试原生代码。

可以直接在sdk下载这些组件:

1、在打开的项目中,从菜单栏选择 Tools > Android > SDK Manager。

2、点击 SDK Tools 标签。

3、选中 LLDB、CMake 和 NDK 旁的复选框。

这里写图片描述

4、点击 Apply,然后在弹出式对话框中点击 OK。

5、安装完成后,点击 Finish,然后点击 OK。

创建一个由cmake构建jni的项目

首先创建项目:

这里写图片描述

注意勾选 Include C++ Support 。然后一直next。到了这一步

这里写图片描述

  • C++ Standard:使用下拉列表选择您希望使用哪种 C++ 标准。选择 Toolchain Default 会使用默认的 CMake 设置。

  • Exceptions Support:如果您希望启用对 C++ 异常处理的支持,请选中此复选框。如果启用此复选框,Android Studio 会将 -fexceptions 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake。

  • Runtime Type Information Support:如果您希望支持 RTTI,请选中此复选框。如果启用此复选框,Android Studio 会将 -frtti 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake。

在 Android Studio 完成新项目的创建后,请从 IDE 左侧打开 Project 窗格并选择 Android 视图。如图 2 中所示,Android Studio 将添加 cpp 和 External Build Files 组:

这里写图片描述

android studio已经自动帮我们生成了一个.cpp和CMakeLists.txt.点击运行后:

1、Gradle 调用您的外部构建脚本 CMakeLists.txt。

2、CMake 按照构建脚本中的命令将 C++ 源文件 native-lib.cpp 编译到共享的对象库中,并命名为 libnative-lib.so,Gradle 随后会将其打包到 APK 中。

3、运行时,应用的 MainActivity 会使用 System.loadLibrary() 加载原生库。现在,应用可以使用库的原生函数 stringFromJNI()。

4、MainActivity.onCreate() 调用 stringFromJNI(),这将返回“Hello from C++”并使用这些文字更新 TextView。

注:Instant Run 与使用原生代码的项目不兼容。Android Studio 会自动停用此功能

如果您想要验证 Gradle 是否已将原生库打包到 APK 中,可以使用 APK 分析器:

1、选择 Build > Analyze APK。

2、从 app/build/outputs/apk/ 目录中选择 APK 并点击 OK。

3、如图中所示,您会在 APK 分析器窗口的 lib// 下看到 libnative-lib.so。

这里写图片描述

添加自己的.so

还是在刚才的项目中,在app/src/main/cpp目录下,创建一个.c/.cpp文件,我这里就创建.cpp了,名字是test。

这里写图片描述

里面内容:

#include <jni.h>#include <string>extern "C"JNIEXPORT jstring JNICALLJava_com_chenxin_testndk_MainActivity_get(        JNIEnv *env,        jobject /* this */) {    std::string hello = "Hello from C++ , holy shit !";    return env->NewStringUTF(hello.c_str());}

然后在CMakeLists.txt中加入:

add_library( # Sets the name of the library."MyLib"是生成后的.so的名字             MyLib             # Sets the library as a shared library.             SHARED             # Provides a relative path to your source file(s)."test.cpp"是刚才创建的             src/main/cpp/test.cpp )

回到MainActivity中,添加三行代码:

public class MainActivity extends AppCompatActivity {    // Used to load the 'native-lib' library on application startup.    static {        System.loadLibrary("native-lib");        **System.loadLibrary("MyLib");**//加载.so    }    @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());        **Log.e("infoo","调用jni的结果 : "+get());**//打印输出    }    /**     * A native method that is implemented by the 'native-lib' native library,     * which is packaged with this application.     */    public native String stringFromJNI();    **public native String get();**声明native方法}

ok,编译运行:

这里写图片描述

6 0
原创粉丝点击