我最近在看 godot 的源代码,目前关注点在于 godot android editor 部分,请结合 godot 源代码,帮我分析一下一个 C++ 项目是如何打包成 Android App 的
Android 环境搭建
这里按照 Godot 官方文档给出方式安装 Android 需要的各种依赖,并会添加适当的补充
-
Java
-
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 Inspector 或 RenderDoc 调试图形问题
- 性能敏感部分可保留 C++,UI 逻辑用 Java/Kotlin
五、打包与发布
- 在 Android Studio 中点击 Build > Build Bundle(s) / APK
- 生成的 APK 或 AAB 可直接安装或上传到 Google Play
六、可选方案(高级)
- 使用 Vulkan 替代 OpenGL ES(更高性能,但更复杂)
- 使用 SDL2 或 Qt 等跨平台框架简化移植(它们已封装 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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。