[关闭]
@cxm-2016 2016-11-21T12:07:22.000000Z 字数 3472 阅读 4662

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

OpenGL-ES

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

发布于作业部落简书


前言

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



一、在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编译器如何去编译我们的源文件,打开文件我们会看见如下内容(注释已精简)。

  1. # 这里指定了CMake的最低版本为3.4.1
  2. cmake_minimum_required(VERSION 3.4.1)
  3. # 这里用来添加一个库
  4. add_library( # 这里设置so库的名称为native-lib
  5. native-lib
  6. # 这里设置该库为共享
  7. SHARED
  8. # 这里是源文件的路径,可以有多个,最终这个源文件将被编译并打包进native-lib库。
  9. src/main/cpp/native-lib.cpp )
  10. # 这里用来查找一个库,并设置到路径变量中去
  11. find_library( # 设置路径变量
  12. log-lib
  13. # 你希望CMake编译器加载的NDK函数库
  14. log )
  15. # 将一个库关联到目标函数库中
  16. target_link_libraries( # 目标函数库
  17. native-lib
  18. # 想要在目标函数库中使用的函数库,其中${路径变量}
  19. ${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,其中的内容为

  1. public class HelloJniLib {
  2. public static native String helloJNI();
  3. }

3.2 创建源文件

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

  1. #include <jni.h>
  2. extern "C"
  3. JNIEXPORT jstring JNICALL
  4. Java_com_github_cccxm_ndk_lib_HelloJniLib_helloJNI(JNIEnv *env,
  5. jobject thiz) {
  6. #if defined(__arm__)
  7. #if defined(__ARM_ARCH_7A__)
  8. #if defined(__ARM_NEON__)
  9. #if defined(__ARM_PCS_VFP)
  10. #define ABI "armeabi-v7a/NEON (hard-float)"
  11. #else
  12. #define ABI "armeabi-v7a/NEON"
  13. #endif
  14. #else
  15. #if defined(__ARM_PCS_VFP)
  16. #define ABI "armeabi-v7a (hard-float)"
  17. #else
  18. #define ABI "armeabi-v7a"
  19. #endif
  20. #endif
  21. #else
  22. #define ABI "armeabi"
  23. #endif
  24. #elif defined(__i386__)
  25. #define ABI "x86"
  26. #elif defined(__x86_64__)
  27. #define ABI "x86_64"
  28. #elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
  29. #define ABI "mips64"
  30. #elif defined(__mips__)
  31. #define ABI "mips"
  32. #elif defined(__aarch64__)
  33. #define ABI "arm64-v8a"
  34. #else
  35. #define ABI "unknown"
  36. #endif
  37. return env->NewStringUTF("Hello from JNI ! Compiled with ABI " ABI ".");
  38. }

3.3 修改CMakeList.txt文件

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

  1. elseif (${ANDROID_PLATFORM_LEVEL} LESS 18)
  2. add_definitions("-DDYNAMIC_ES3")
  3. set(OPENGL_LIB GLESv2)
  4. else ()
  5. set(OPENGL_LIB GLESv3)
  6. endif (${ANDROID_PLATFORM_LEVEL} LESS 11)
  7. add_library(ndk-lib SHARED
  8. src/main/cpp/hello-jni.cpp)
  9. target_link_libraries(ndk-lib
  10. android
  11. log
  12. m)

3.4 在Activity中显示结果

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

  1. <TextView
  2. android:text="TextView"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content"
  5. android:id="@+id/tv_hello_jni" />
  1. class HelloJniActivity : AppCompatActivity() {
  2. override fun onCreate(savedInstanceState: Bundle?) {
  3. super.onCreate(savedInstanceState)
  4. setContentView(R.layout.activity_hello_jni)
  5. tv_hello_jni.text = HelloJniLib.helloJNI()
  6. }
  7. }

3.5 加载本地库

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

  1. class NDKApplication : Application() {
  2. init {
  3. System.loadLibrary("ndk-lib")
  4. }
  5. }

3.6 小结

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


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

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注