JNI --- AS,CMake的简单使用,DEMO

【记录】需要完成一些NDK的简单开发工作,平时不常接触这部分知识,记录下CMAKE的简单使用和JNI的基础

1. 配置

AS的2.2及以上版本可以使用CMAKE,相对于之前使用ndk-build,要简单很多。

1)下载NDK,设置gradle

可以通过AS下载CMake,LLDB以及NDK

 NDK也可以自己从官网下载,然后在local.properties文件中设置ndk的路径,例如

ndk.dir=D\:\\ndk\\android-ndk-r16b

2)创建新项目

在创建项目的向导中,我们可以选择支持c++的选项。在后面的编译中就会,项目会生成对应的CMakeLists.txt配置模块gradle文件并生成一个示例的native-lib.cpp文件和对应的MainActivity(其中声明了native方法)。

//模块的gradle文件
android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.hik.face.sdk"
        minSdkVersion 19
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        //cmake相关
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    //cmake相关
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

 借用下别人的图,生成的native-lib.cpp

è¿éåå¾çæè¿°

//MainActivity.java

// Used to load the 'native-lib' library on application startup.
    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());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

 到这里,就可以跑起来一个简单的demo了。但是实际开发中,库的名字,文件名等内容,都需要修改,或者会创建新的文件,生成新的库。

2. DEMO

默认生成的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.

# 配置so库信息
add_library( # Sets the name of the library.
            # 生成的so库名称,此处生成的so文件名称是libnative-lib.so
             native-lib

             # Sets the library as a shared library.
             # STATIC:静态库,是目标文件的归档文件,在链接其它目标的时候使用
             # SHARED:动态库,会被动态链接,在运行时被加载
             # MODULE:模块库,是不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数动态链接
             SHARED

             # Provides a relative path to your source file(s).
             # 资源文件,可以多个,
             # 资源路径是相对路径,相对于本CMakeLists.txt所在目录
             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.
              # android系统每个类型的库会存放一个特定的位置,而log库存放在log-lib中
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              # android系统在c环境下打log到logcat的库
              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} )

如果我们要创建新的文件,可以参照上面的再配置下(这里把native-lib.cpp删了,相关的配置也删除)

# 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.
              # 新的库名字叫detect
              detect

              # Sets the library as a shared library.
              # 还是共享库
              SHARED

              # Provides a relative path to your source file(s).
              # 关联路径下的detect.cpp文件
              src/main/cpp/detect.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.

# 这里没变,还是使用log-lib作为log的名称
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.

# 为了后面detect库打日志,这里也关联上
target_link_libraries( # Specifies the target library.
                      detect

                      # Links the target library to the log library
                      # included in the NDK.
                      ${log-lib} )

创建Detect.java文件,生命native方法

public class Detect {
    static {
        System.loadLibrary("detect");
    }

    public native String getStrContent();
}

然后在cpp下创建detect.cpp文件。这里如果通过alt+enter提示的方式生成对应的代码,as会在/main/jni下面生成一个.c文件,那么就和上面修改的配置不相符了。这里可以选择手动生成文件写代码,或者修改上面的cmake配置后,通过alt+enter的方式生成方法。

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

extern "C" JNIEXPORT jstring

JNICALL
//com_xxx_xxx_xxx是包名,Detect是Java类名,getStrContent是方法名
Java_com_xxx_xxx_xxx_Detect_getStrContent(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from myc++";
    return env->NewStringUTF(hello.c_str());
}

 最后,稍微修改下MainActivity就可以运行了

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

        Detect detector = new Detect();
        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(detector.getStrContent());

    }

这只是非常简单的demo,不能满足真正的需求,边学习便补充。

参考

https://blog.csdn.net/quwei3930921/article/details/78820991

https://developer.android.google.cn/studio/projects/add-native-code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值