这里说一下如何将SDL编译为App。参考文档是SDL源码下的docs/README-android.md。
前期准备
需要准备:
- android sdk工具和ndk工具
- JDK8(更高的应该也可以)
- SDL2的源代码(这里使用的是SDL2_2.0.14版本)
- make,CMake(如果你用的Android Studio或者Gradle就不需要CMake和make)
- Gradle(最新版本就行,我这里是7.2)
Android SDK和NDK工具的配置
不会的看这里。
最近MacOS上好像不能用sdk-manager了,直接下载SDK和NDK解压,然后设置环境变量就行了。
要求 SDK >= 26, NDK >= r15c
要设置如下四个环境变量:
| |
再给出目录结构,按照这个配就行了,用sdk-manager安装更方便:
| |
配置安卓工程
使用SDL自己的脚本自动生成
进入SDL源码下的build-scripts/,里面有个androidbuild.sh。执行这个文件就可以帮你自动生成工程了。
这个文件有两个执行方法:
| |
第一个参数是你的包签名。后面的参数是你的源文件(你也可以将文件名称写在sources.list中然后用第一条命令给他)。
源文件我建议将头文件和源文件都给他,不然它会找不到头文件。
执行结果:
| |
它会给你提示,说在../build/下面已经生成了com.visualgmq.test工程了,进去后./gradlw installDebug就可以了。
这里的gradlw命令会编译之后直接真机运行,如果你只是想编译打包成APK,那么请使用gradlw build。
手动配置工程
自动生成的方法只有拥有Bash环境才能执行,Windows下不行。而且我们也需要搞清楚到底发生了什么,以便于更好地自定义工程。
- 首先将SDL源码根目录下的
android-project目录拷贝出来,这个就是你的Android工程目录(可以随意改名)。 - 然后将SDL源码link到Android工程目录下的
app/jni目录下,或者直接将SDL源码下的include,src,Android.mk文件拷贝到app/jni/SDL目录下。
这是基本配置,然后你要根据使不使用CMake来进行配置:
不使用CMake的工程
打开
app/jni/src/Android.mk1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := main SDL_PATH := ../SDL LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include # Add your application source files here... LOCAL_SRC_FILES := YourSourceHere.c LOCAL_SHARED_LIBRARIES := SDL2 LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog include $(BUILD_SHARED_LIBRARY)将
SDL_PATH := ../SDL修正为你刚刚link的SDL源码目录。增加你的源文件和头文件:
Android.mk中的LOCAL_SRC_FILES变量就是你的源文件名称。这里改成你自己的源文件。头文件的搜索目录要加到LOCAL_C_INCLUDES中。
注意源文件要放在app/jni/src目录下。
使用CMake的工程
- 打开
app/build.gradle,将里面的ndkBuild部分注掉(2024行,4345行),然后将cmake部分解注(2530行,4648行)。 - 编辑
app/jni/CMakeLists.txt来适配你的工程。这里有一些注意点:- 注意11行
add_subdirectory(SDL)指定了你刚刚link或copy过来的SDL源码目录,要改成一样的名字。 - 你真正的工程CMakeLists在
app/jni/src下。
- 注意11行
编译工程,生成APK,真机调试
如果你使用Android Studio,那你直接用AS打开工程就可以了。
如果你用的gradle,那:
| |
其他对工程的DIY
自定义App名称和包名
将
app/src/main/AndroidManifest.xml中的package="org.libsdl.app"一行设置为你自己的包名。然后在
app/src下创建一个和包名一样的路径以及一个java文件(例如com/gamemaker/game/MyGame.java)在
MyGame.java中增加如下内容:1 2 3 4 5 6 7 8 9package com.gamemaker.game; import org.libsdl.app.SDLActivity; /** * A sample wrapper class that just calls SDLActivity */ public class MyGame extends SDLActivity { }改
AndroidManifest.xml中的<activity android:name="SDLActivity"中的SDLActivity改为你的类名(这里是MyGame)。
更改App的图标
替换app/src/main/res下所有文件夹中的ic_launcher.png就可以了。
使用STL
如果你要使用C++ STL,在app/jni/Application.mk中解注APP_STL := c++_shared一行。
编码的注意事项
资源加载
在app/src/main/assets文件夹下的东西会被视为资源一并打包到APK中。可以使用SDL_rwops.h中声明的函数来读取。
暂停App
如果你设置了SDL_HINT_ANDROID_BLOCK_ON_PAUSEHint,这样当App暂停时事件循环也会自动暂停。
当App继续执行时,SDL将尝试自动恢复GL上下文。 在现代设备(Android 3.0及以上)中,这将最有可能获得成功。但是在一些老设备上会失败。
窗口的创建和大小
创建窗口的正确姿势:
| |
总之你不应该给窗口标题和大小。窗口的大小是由你的设备屏幕决定的,你应当在窗口创建成功后使用SDL_GetWindowSize()来获得大小。
退出程序的正确姿势
- 在
main函数中返回。 - 可能有什么操作导致你的程序要关闭,这个时候会发送一个
SDL_QUIT事件给你。
注:不要使用exit()函数退出!这不是合法的退出方法。
设置横屏
App默认是竖屏显示,使用SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight")即可横屏显示。
加载第三方库
这里只说明如何通过CMake加载。
打开app/jni/CMakeLists.txt,可以发现他已经给我们写好了:
| |
意思就是说你要用什么库,就将这些库的源代码放在app/jni下,然后对相应的行解注(放置方法就和SDL一样,你也可以link过来)。
需要注意的是,第三方库的代码请从github上的sdl-org用户下进行下载,那个是SDL最新的代码。在liblsdl.org/projects/下下载的代码中有些不包含CMakeLists.txt。