我最近在看 godot 的源代码,目前关注点在于 godot android editor 部分,请结合 godot 源代码,帮我分析一下一个 C++ 项目是如何打包成 Android App 的

Android 环境搭建

这里按照 Godot 官方文档给出方式安装 Android 需要的各种依赖,并会添加适当的补充

  1. Java

  2. Gradle
    设置 GRADLE_USER_HOME
    这里我们为什么要GRADLE_USER_HOME,其实这个就算不设置也是可以的没有什么问题,因为会默认在用户目录下创建一个.gradle文件夹由于存放gradle的各个版本,比如C:\Users\Administrator.gradle,但是这样会有两点不好,1、切换用户时需要重新下载更新。2、时间长了,版本多了会占用c盘存储,所以我设置了环境变量GRADLE_USER_HOME,并赋值为E:\android\gradlepro,这样就好了

Android Ndk Dev 入门

将一个 C++ OpenGL 项目打包成 Android 应用,主要依赖于 Android NDK(Native Development Kit)JNI(Java Native Interface)。Android 支持使用 C/C++ 编写图形渲染代码(如 OpenGL ES),并通过 Java/Kotlin 与原生代码交互。以下是完整的步骤指南:


一、前提条件

  • 已安装 Android Studio(推荐最新稳定版)
  • 安装了 NDK、CMake 和 LLDB(可通过 SDK Manager 安装)
  • 你的 C++ OpenGL 项目使用的是 OpenGL ES(而非桌面 OpenGL),因为 Android 不支持完整 OpenGL
  • 项目结构清晰,渲染逻辑封装良好(便于移植)

二、项目结构概览

Android 项目通常包含:

MyApp/
├── app/
│   ├── src/main/
│   │   ├── java/com/example/myapp/     ← Java/Kotlin 代码(Activity)
│   │   ├── cpp/                         ← C++ 原生代码(你的 OpenGL 项目)
│   │   └── AndroidManifest.xml
│   ├── CMakeLists.txt                   ← 构建 C++ 的脚本
│   └── build.gradle                     ← 配置 NDK/CMake

三、具体步骤

1. 创建 Android 项目

在 Android Studio 中:

  • 新建项目 → 选择 “Empty Activity”(语言选 Java 或 Kotlin)
  • 勾选 “Include C++ support”(或手动配置 NDK)

2. 配置 build.gradle(Module: app)

确保启用了 NDK 和 CMake:

android {
    ...
    defaultConfig {
        ...
        ndk {
            abiFilters 'arm64-v8a', 'armeabi-v7a' // 根据需要添加 x86_64 等
        }
    }

    externalNativeBuild {
        cmake {
            path file('CMakeLists.txt')
            version '3.22.1' // 或你安装的版本
        }
    }
}

3. 编写 CMakeLists.txt

示例 CMakeLists.txt

cmake_minimum_required(VERSION 3.22.1)
project("myopenglapp")

# 添加你的 C++ 源文件
add_library(
    myopengl-lib
    SHARED
    src/main/cpp/native-lib.cpp
    src/main/cpp/Renderer.cpp
    # 添加你的其他 .cpp 文件
)

# 链接 OpenGL ES 和 log 库
find_library(
    log-lib
    log
)

target_link_libraries(
    myopengl-lib
    GLESv3          # 或 GLESv2
    EGL
    ${log-lib}
)

注意:Android 使用 OpenGL ES,不是桌面 OpenGL。确保你的代码使用 #include <GLES3/gl3.h> 等头文件。

4. 编写 JNI 接口(native-lib.cpp)

这是 Java/Kotlin 与 C++ 的桥梁:

#include <jni.h>
#include <GLES3/gl3.h>
#include <android/log.h>

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "MyApp", __VA_ARGS__))

extern "C" {

// 初始化 OpenGL 上下文后调用
JNIEXPORT void JNICALL
Java_com_example_myapp_MainActivity_initGL(JNIEnv *env, jobject thiz) {
    // 初始化你的 OpenGL 资源(shader、VBO 等)
    LOGI("initGL called");
}

// 每帧渲染调用
JNIEXPORT void JNICALL
Java_com_example_myapp_MainActivity_drawFrame(JNIEnv *env, jobject thiz) {
    glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // 调用你的渲染逻辑
}

} // extern "C"

5. Java/Kotlin 端:使用 GLSurfaceView

MainActivity.kt(或 .java)中:

class MainActivity : AppCompatActivity() {

    private lateinit var glView: GLSurfaceView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        glView = GLSurfaceView(this)
        glView.setEGLContextClientVersion(3) // 使用 OpenGL ES 3.0
        glView.setRenderer(MyRenderer())
        setContentView(glView)
    }

    override fun onPause() {
        super.onPause()
        glView.onPause()
    }

    override fun onResume() {
        super.onResume()
        glView.onResume()
    }
}

class MyRenderer : GLSurfaceView.Renderer {
    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        initGL() // 调用 native 方法
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        // 设置视口
    }

    override fun onDrawFrame(gl: GL10?) {
        drawFrame() // 调用 native 渲染
    }

    // 声明 native 方法
    external fun initGL()
    external fun drawFrame()

    companion object {
        init {
            System.loadLibrary("myopengl-lib")
        }
    }
}

6. 移植你的 OpenGL 代码

  • 将你的 C++ 渲染逻辑(如 shader 加载、矩阵计算、draw call)放入 drawFrame
  • 替换所有 #include <GL/gl.h>#include <GLES3/gl3.h>
  • 使用 glGenBuffers, glVertexAttribPointer 等 ES 版本函数
  • 注意:Android 不支持固定管线(如 glBegin/glEnd

f# 四、调试与优化

  • 使用 __android_log_print 打印日志(需链接 log 库)
  • 使用 Android GPU InspectorRenderDoc 调试图形问题
  • 性能敏感部分可保留 C++,UI 逻辑用 Java/Kotlin

五、打包与发布

  • 在 Android Studio 中点击 Build > Build Bundle(s) / APK
  • 生成的 APK 或 AAB 可直接安装或上传到 Google Play

六、可选方案(高级)

  • 使用 Vulkan 替代 OpenGL ES(更高性能,但更复杂)
  • 使用 SDL2Qt 等跨平台框架简化移植(它们已封装 Android GL 上下文)
  • 使用 CMake + ndk-build 直接命令行构建(适合 CI/CD)

Android C++ 和 Java 通信

Godot Android Scons


def get_android_ndk_root(env: "SConsEnvironment"):
    return env["ANDROID_HOME"] + "/ndk/" + get_ndk_version()


# This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
def get_ndk_version():
    return "23.2.8568313"



# Check if Android NDK version is installed
# If not, install it.
def install_ndk_if_needed(env: "SConsEnvironment"):
    sdk_root = env["ANDROID_HOME"]
    if not os.path.exists(get_android_ndk_root(env)):
        extension = ".bat" if os.name == "nt" else ""
        sdkmanager = sdk_root + "/cmdline-tools/latest/bin/sdkmanager" + extension
        if os.path.exists(sdkmanager):
            # Install the Android NDK
            print("Installing Android NDK...")
            ndk_download_args = "ndk;" + get_ndk_version()
            subprocess.check_call([sdkmanager, ndk_download_args])
        else:
            print_error(
                f'Cannot find "{sdkmanager}". Please ensure ANDROID_HOME is correct and cmdline-tools'
                f' are installed, or install NDK version "{get_ndk_version()}" manually.'
            )
            sys.exit(255)
    env["ANDROID_NDK_ROOT"] = get_android_ndk_root(env)

参考资料


如果你已有具体的 C++ OpenGL 项目,我可以帮你分析如何适配到 Android 结构中。欢迎提供代码片段或项目结构!

=========================
https://blog.csdn.net/chenby186119/article/details/146077167

%ANDROID_HOME%\platform-tools

作者:vencol
链接:https://www.jianshu.com/p/378930364493
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。