Android音视频系列

OpenGL-ES 3.0学习指南(一)——Hello NDK

2016-11-21  本文已影响529人  798fe2ac8685

标签(空格分隔): OpenGL-ES

版本:1
作者:陈小默
声明:禁止商业,禁止转载

发布于作业部落简书


前言

本篇内容介绍NDK环境的基本搭建和最简单的NDK示例。示例工程发布到GitHub-NDK。在开始本系列之前,请确保已经了解JNI的相关知识,如果没有,可以到这里学习JNI完全指南系列。水平有限,如有错误,恳请批评指正。


[toc]


一、在Android Studio 2.2及以上版本搭建NDK开发环境

Android Studio在其2.2及以上版本继承了流行的C++编译器CMake,于是我们很方便的就能够搭建出NDK开发环境。

1.1 创建NDK工程

在Android Studio 2.2 及以上版本创建NDK的工程只需要勾选Include C++ Support即可。

1.2 CMakeList.txt文件说明

在工程创建完成之后,我们将目录视图切换到Project,我们发现app目录下多了一个CMakeList.txt文件,这个文件的作用是指引CMake编译器如何去编译我们的源文件,打开文件我们会看见如下内容(注释已精简)。

# 这里指定了CMake的最低版本为3.4.1
cmake_minimum_required(VERSION 3.4.1)
# 这里用来添加一个库
add_library( # 这里设置so库的名称为native-lib
             native-lib
             # 这里设置该库为共享
             SHARED
             # 这里是源文件的路径,可以有多个,最终这个源文件将被编译并打包进native-lib库。
             src/main/cpp/native-lib.cpp )
# 这里用来查找一个库,并设置到路径变量中去
find_library( # 设置路径变量
              log-lib
              # 你希望CMake编译器加载的NDK函数库
              log )
# 将一个库关联到目标函数库中
target_link_libraries( # 目标函数库
                       native-lib
                       # 想要在目标函数库中使用的函数库,其中${路径变量}
                       ${log-lib} )

更详细的CMakeList.txt可以参照这里CMakeList.txt说明。


二、使用Android Studio搭建Kotlin开发环境

目前kotlin语言的版本是1.0.4。搭建过程详见在Android Studio中配置Kotlin开发环境


三、Hello JNI

本章内容为调用JNI方法,并返回一段字符串。

3.1 创建Java文件

在{$package}/lib包下创建一个Java文件HelloJniLib.java,其中的内容为

public class HelloJniLib {
    public static native String helloJNI();
}

3.2 创建源文件

当我们声明了一个native方法后,需要在一个源文件中实现业务逻辑,接下来,我们在cpp文件夹下创建一个hello-jni.cpp,并在其中实现声明的本地方法:

#include <jni.h>

extern "C"
JNIEXPORT jstring JNICALL
Java_com_github_cccxm_ndk_lib_HelloJniLib_helloJNI(JNIEnv *env,
                                                   jobject thiz) {
#if defined(__arm__)
    #if defined(__ARM_ARCH_7A__)
        #if defined(__ARM_NEON__)
            #if defined(__ARM_PCS_VFP)
                #define ABI "armeabi-v7a/NEON (hard-float)"
            #else
                #define ABI "armeabi-v7a/NEON"
            #endif
        #else
            #if defined(__ARM_PCS_VFP)
                #define ABI "armeabi-v7a (hard-float)"
            #else
                #define ABI "armeabi-v7a"
            #endif
        #endif
    #else
        #define ABI "armeabi"
    #endif
#elif defined(__i386__)
    #define ABI "x86"
#elif defined(__x86_64__)
    #define ABI "x86_64"
#elif defined(__mips64)  /* mips64el-* toolchain defines __mips__ too */
    #define ABI "mips64"
#elif defined(__mips__)
    #define ABI "mips"
#elif defined(__aarch64__)
    #define ABI "arm64-v8a"
#else
    #define ABI "unknown"
#endif
    return env->NewStringUTF("Hello from JNI !  Compiled with ABI " ABI ".");
}

3.3 修改CMakeList.txt文件

在这里我们需要指定生成的so库的名字,还有需要被编联到这个库的源文件的位置,注意,这里的源文件路径是相对于CMakeList.txt的路径。这里我们指定库名为ndk-lib。

elseif (${ANDROID_PLATFORM_LEVEL} LESS 18)
  add_definitions("-DDYNAMIC_ES3")
  set(OPENGL_LIB GLESv2)
else ()
  set(OPENGL_LIB GLESv3)
endif (${ANDROID_PLATFORM_LEVEL} LESS 11)

add_library(ndk-lib SHARED
            src/main/cpp/hello-jni.cpp)

target_link_libraries(ndk-lib
                      android
                      log
                      m)

3.4 在Activity中显示结果

接下来我们需要一个用来显示结果的ActivityHelloJniActivity,其中包含一个TextView

    <TextView
        android:text="TextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_hello_jni" />
class HelloJniActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_hello_jni)

        tv_hello_jni.text = HelloJniLib.helloJNI()
    }
}

3.5 加载本地库

在使用本地方法之前,我们需要通知JVM加载本地库,由于本地库仅需要加载一次,而且必须在使用native方法之前,所以这里可以将加载过程放置到Application类中,这样程序启动时就会自动链接本地库。

class NDKApplication : Application() {
    init {
        System.loadLibrary("ndk-lib")
    }
}

3.6 小结

到此为止,我们的第一个程序就完成了,如果运行以上程序,我们就能在Activity上看到JNI方法返回的数据。现在我们总结一下一个NDK程序的开发过程:


下一篇:OpenGL-ES 3.0学习指南(二)——Hello Java

上一篇下一篇

猜你喜欢

热点阅读