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 分支

相关推荐
谢白羽3 小时前
vllm实践
android·vllm
电子云与长程纠缠3 小时前
Godot学习03 - 实例化、层级访问、Export
android·学习·godot
毕设源码-朱学姐4 小时前
【开题答辩全过程】以 基于Android的便民系统的设计与实现为例,包含答辩的问题和答案
android
鬼蛟4 小时前
Spring————事务
android·java·spring
qq_170264755 小时前
unity出安卓年龄分级的arr包问题
android·unity·游戏引擎
kejiashao7 小时前
Android View的绘制流程及事件分发机制
android
小蜜蜂嗡嗡7 小时前
flutter实现付费解锁内容的遮挡
android·flutter
进击的cc7 小时前
拒绝背诵!一文带你打穿 Android ANR 发生的底层全链路
android·面试
进击的cc8 小时前
App 启动优化全家桶:别再只盯着 Application 了,热启动优化你真的做对了吗?
android·面试
彭波3968 小时前
安卓手机端安装xapk、apkm软件!怎样安装xapk软件?安卓的apk和XAPK的区别?附教程
android·智能手机