【环境】
Android Studio:3.5.2
Gradle:5.4.1
NDK:21.3.6528147
JDK:1.8
photon-androidndk-sdk_v4-1-16-3
【背景】
photon engine针对Unity开发的插件PUN2用于多人在线比较简单方便使用,以前只用在Unity中使用,甚少关注原生安卓和IOS如何使用,最近有个需求,需要用原生安卓APP(已开发完毕)与Unity项目(开发中)做数据同步,尽量用现有工具(SDK)做,既然不用造轮子,就用这个了。结果踩坑了,原生安卓SDK,官方用VS+VisualGDB开发的,不是直接用Android Studio,有不少的差异,而且无完整教程,官网论坛不少人吐槽Android Demo无法运行。因对原生安卓手生,历经不少曲折,记录如下。
【尝试】
下载解压后目录结构如下:
尝试用Android Studio打开demo_loadBalancing工程,几经波折,都以失败告终。首先,理解这套东西的流程:
- NDK,使用C(或C++)语言书写逻辑,好处是代码移植和代码保护。
- JNI,用于Java和C(或C++)进行交互。
- .a文件,静态链接库,在SDK中Common-cpp、Photon-cpp、LoadBalancing-cpp文件夹中已生成.a静态库文件。
- .so文件,动态链接库,可手动生成。
尝试过程中,发现了些容易忽略的问题,NDK r18及以后版本对应Android.mk文件配置是需要进行修改的:
再次经过多次尝试和验证,得到一经验,因demo_loadBalancing目录结构和Android Studio默认不同,所以想以最小误差跟踪问题,又因为NDK及JNI调用对包名有要求,.a静态链接库引用对路径有要求,所以想重建相同项目名称、相同包名、相同目录的新Android Studio工程。
【Android Studio重建demo_loadBalancing工程】
- 安装Android Studio,并在管理器内安装NDK 21.*
- 官网下载Photon RealTime : Android NDK SDK
- 解压至安卓工程目录
- 进入*\photon-androidndk-sdk_v4-1-16-3\Demos\目录,将文件夹demo_loadBalancing重命名demo_loadBalancing_old,备用,并新建demo_loadBalancing空文件夹
- 打开Android Studio新建项目:项目名称、包名、Activity名称及工程目录和旧的demo_loadBalancing工程完全保持一致。
- 在Android Studio编辑器中,打开“Project Structure”窗口,进入“SDK Location”目录,指定SDK、NDK、JDK对应目录。
- 在Android Studio编辑器中,切换为"Project"模式,复制老工程代码:【旧工程--->新工程】
DemoActivity.java------>DemoActivity.java strings.xml------------>strings.xml main.xml--------------->activity_main.xml jni文件夹--------------->src/main/jni文件夹 */inc/NetworkLogic.h---->src/main/jni/NetworkLogic.h */src/NetworkLogic.cpp-->src/main/jni/NetworkLogic.cpp */src/StdIO_main.cpp---->src/main/jni/StdIO_main.cpp
-
修改src/main/jni/Android.mk文件,其相对于旧工程目录结构发生了变化
LOCAL_PATH := $(call my-dir) PHOTON_SDK_ROOT := $(LOCAL_PATH)/../../../../../.. include $(CLEAR_VARS) LOCAL_MODULE := demoLoadBalancing #VisualGDBAndroid: AutoUpdateSourcesInNextLine LOCAL_SRC_FILES := NetworkLogic.cpp AndroidNetworkLogic.cpp main.cpp LOCAL_C_INCLUDES := $(PHOTON_SDK_ROOT) ../inc/ ../../../../shared/inc LOCAL_CFLAGS := -Werror-implicit-function-declaration -Wall -DEG_DEBUGGER -D__STDINT_LIMITS -D_EG_ANDROID_PLATFORM LOCAL_STATIC_LIBRARIES := loadbalancing-cpp-static-prebuilt photon-cpp-static-prebuilt common-cpp-static-prebuilt LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY) $(call import-add-path, $(PHOTON_SDK_ROOT)/LoadBalancing-cpp/lib) $(call import-module,loadbalancing-cpp-prebuilt)
-
修改src/main/jni/Application.mk文件
APP_ABI := all APP_STL := c++_static APP_CPPFLAGS := -std=c++11 APP_PLATFORM := android-22
-
修改photon-androidndk-sdk_v4-1-16-3根目录下:
Common-cpp/lib/common-cpp-prebuilt/Android.mk Photon-cpp/lib/photon-cpp-prebuilt/Android.mk LoadBalancing-cpp/lib/loadbalancing-cpp-prebuilt/Android.mk 三个文件内的属性: 【LOCAL_SRC_FILES := *.a】------>【LOCAL_SRC_FILES := *_libc++.a】
-
修改 */app/src/build.gradle:
ndk{ moduleName"demoLoadBalancing" //生成的so文件名字,调用C程序的代码中会用到该名字 abiFilters 'armeabi-v7a', 'armeabi','x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a' } ----------------------------------------------------------------------------------- sourceSets.main { jniLibs.srcDir 'src/main/libs' jni.srcDirs = [] //disable automatic ndk-build call }
-
修改 */gradle.properties:
android.useDeprecatedNdk=true
-
修改NetworkLogic.cpp文件,填写realtime app id,当连接self-hosted时,可忽略:
appID = L"5bbcb58f-fea4-4b29-b422-685ba8d3caff";
-
修改NetworkLogic.cpp文件,重置服务器IP地址,代码默认是A模式,有四个默认参数,中国区可以选择B模式,我选择的是C模式,需要注意不同模式下ServerType有所不同。当连接self-hosted模式时,需要提前设定user id参数。
-
打开File-Settings窗口,进入【Tools/External Tools】模块,点击"+"分别创建ndk-build、javah扩展工具
-
鼠标右键“jni”目录:执行[External Tools/ndk-build],生成对应.so文件
-
修改AndroidManifest.xml文件新增权限:
<permission-group android:name="android.permission-group.NETWORK" /> <uses-permission android:name="android.permission.INTERNET" />
-
最后,选择目标设备(模拟器),Run
参考:
【完】