Android OpenGL 教程——Native 工程初始化

NativeActivity

NDK 的适用场景官方给出三点:

  1. 平台间的 App 移植
  2. 复用现有库
  3. 对软件性能要求较高的场合比如游戏等

有两种方式可以实现 native activity。

  1. native_activity.h
  2. android_native_app_glue

由于第二种方法启用另一个线程处理回调和输入事件,NDK 的例子中就采用了这个实现方式。

工程初始化

创建 NDK 工程

NDK 工程创建完成会生成一个带有 JNI 调用 c++ 返回 HelloWorld 字符串的一个初始化工程

配置 NativeActivity

首先在 AndroidManifest.xml 文件中添加 Name 为 android.app.lib_name(不可更改) 的 MetaData

XML 复制代码
<activity
    android:name=".MainActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <meta-data android:name="android.app.lib_name" android:value="OpenGLDemo" />

</activity>

将我们 MainActivity 改为继承 NativeActivity,并加载 native 生成的 OpenGLDemo.so

java 复制代码
import android.app.NativeActivity
class MainActivity : NativeActivity() {
    companion object {
        init {
            System.loadLibrary("OpenGLDemo")
        }
    }
}

配置 CMakeList 文件

cpp 复制代码
cmake_minimum_required(VERSION 3.22.1)

# 与之前在 Manifest 文件中配置的一样
project("OpenGLDemo")

# 添加 native_app_glue
set(APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue)
include_directories(${APP_GLUE_DIR})
add_library(app-glue STATIC ${APP_GLUE_DIR}/android_native_app_glue.c)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")

# 添加源码和头文件
file(GLOB LOCAL_SOURCE  "${CMAKE_SOURCE_DIR}/*.cpp")
file(GLOB LOCAL_HEADER "${CMAKE_SOURCE_DIR}/*.h")
add_library(${CMAKE_PROJECT_NAME} SHARED
        ${LOCAL_HEADERS}
        ${LOCAL_SOURCE})

# 指定 CMake 应链接到您的目标库的库
target_link_libraries(${CMAKE_PROJECT_NAME}
        android
        EGL
        GLESv3
        jnigraphics
        app-glue
        log)

创建 main.cpp 的 native 入口文件

cpp 复制代码
#include <android_native_app_glue.h>
#include <jni.h>

static int32_t handle_input(struct android_app* app, AInputEvent* event) {
    return 0;
}

static void handle_cmd(struct android_app *app, int32_t cmd) {
    switch (cmd) {
        case APP_CMD_RESUME: {
            break;
        }
        case APP_CMD_PAUSE: {
            break;
        }
        default:
            break;
    }
}

void android_main(struct android_app *app) {
    app->onAppCmd = handle_cmd;
    app->onInputEvent = handle_input;
    // 循环等待要做的事情。
    while (!app->destroyRequested) {
        int events;
        struct android_poll_source *source;
        // 获取需要处理的事件
        if (ALooper_pollAll(0, nullptr, &events, (void **) &source) >= 0) {
            if (source) {
                source->process(app, source);
            }
        }
    }
}

至此我们的 native 工程就配置完成了,运行后你会看到一个纯黑的窗口,那是因为我们没有为当前 MainActivity 创建的 Window 绘制任何东西

要想绘制东西,需要初始化 OpenGL ,创建对应的 Display 与 Surface 与当前的 window 进行绑定

详见 Android OpenGL 教程------窗口初始化

OpenGLDemo 源码的 init_native_activity 分支

相关推荐
帅得不敢出门16 分钟前
Gradle命令编译Android Studio工程项目并签名
android·ide·android studio·gradlew
problc1 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
帅得不敢出门11 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡
我又来搬代码了13 小时前
【Android】使用productFlavors构建多个变体
android
德育处主任15 小时前
Mac和安卓手机互传文件(ADB)
android·macos
芦半山15 小时前
Android“引用们”的底层原理
android·java
迃-幵15 小时前
力扣:225 用队列实现栈
android·javascript·leetcode
大风起兮云飞扬丶15 小时前
Android——从相机/相册获取图片
android
Rverdoser16 小时前
Android Studio 多工程公用module引用
android·ide·android studio
aaajj16 小时前
[Android]从FLAG_SECURE禁止截屏看surface
android