Unity接入华为HMS SDK:版本对齐、配置落地与真机排查
发布时间:2026/11/6 9:02:22 锦皓数字建站

简介这是一份面向Unity开发者与Android应用接入人员的华为HMS SDK演示工程围绕在Unity项目中集成华为账号、游戏、推送等能力提供可直接参照的工程结构与示例代码。压缩包共2000个文件涵盖C#脚本、DLL库、JAR包、Java源码、AndroidManifest等XML配置、资源文件与日志整体约28.82MB既有SDK依赖也保留Unity工程资源与打包产物便于对照排查接入环境。已有1845人学习适合需要了解HMS SDK在Unity中落地方式的初中级开发者。工程内含HuaweiSdkDemo相关示例、初始化与登录等接口调用痕迹、Android插件源码及场景资源可作为搭建测试工程、核对依赖版本和梳理调用链的参考帮助读者理解Unity与华为SDK之间的工程组织方式。1. 版本先对齐Unity 接入华为 HMS SDK 最容易翻车的一步Unity 接入华为 HMS SDK 这件事劝退新人的从来不是代码是版本。我见过太多次unitypackage 导进去了插件菜单点了AndroidManifest 也更新了结果一打包就卡在 Gradle报一串找不到 agconnect-core 的错或者包能装上点开闪退logcat 里只有一句客户端信息为空。这类问题九成不是 SDK 有 bug是 Unity 版本、JDK、Gradle、targetSdkVersion 四者里有一个跟插件要求对不上。这套环境适合已经能把 Unity 项目打出 Android 包、准备接登录、推送、支付这类系统能力的人如果你连一次真机安装都没跑通先回去把空工程打出来别急着上 SDK。2. 装前把环境钉死Unity 版本、JDK 与 Gradle 三件套装 SDK 之前我会先花二十分钟把环境信息抄在一张纸上Unity 具体版本号、JDK 大版本、Gradle 版本、Android targetSdkVersion、包名、签名文件路径。这六项定不下来后面每改一次配置都要重新排一遍雷。最省事的做法是新建一个干净的空工程专门用来验证 SDK跑通之后再往正式工程里搬这样出问题时能立刻判断是 SDK 的问题还是自己项目里其它插件打架。2.1 Unity 与 Android Build Support 的勾选姿势用 Unity Hub 安装编辑器的时候Android Build Support 下面有三个子项必须一起勾Android SDK NDK Tools、OpenJDK。很多人只勾了最外层那个 Android Build Support以为带 SDK 了结果 Preferences 里 External Tools 全是红的一构建就提示找不到 sdkmanager。这个坑不影响编辑器启动只在你点 Build 的那一刻爆发所以特别容易被忽略。版本选择上我的经验是不要追最新。HMS 的 Unity 插件对大版本的支持通常滞后一两个小版本插件 README 里写支持的区间超出区间不是一定不能用但你会成为第一个踩雷的人。下面这张表是我自己用过的组合具体以你下载的插件包里 README 写的为准Unity 版本JDK说明2019.4 LTSJDK 8兼容性最稳老项目迁移常用2020.3 LTSJDK 8我目前主力组合插件适配成熟2021.3 LTSJDK 11需要较新的插件版本Gradle 模板改动多2022 及以上JDK 11谨慎先拿空工程验证装好之后打开 Preferences → External Tools确认 JDK、SDK、NDK、Gradle 四项都有路径。如果用 Unity 自带的就保持默认勾选如果公司要求统一用某一套 Android SDK就把 Unity 自带那几项勾掉手动指过去最忌讳一半自带一半手动路径混着用。2.2 JDK 与 Gradle 的版本对不上会怎么炸JDK 版本不对的报错长这样Unsupported class file major version 55或者构建时提示Could not determine java version。55 对应 JDK 1152 对应 JDK 8看到这行字就说明编译用的 JDK 和你配置的 Gradle 期望的不一致。先跑两条命令确认当前环境# 看系统默认 JDK注意这里是系统环境不是 Unity 里配的那个 java -version # 看 Unity 工程生成的 Gradle 版本 cd Temp/gradleOut ./gradlew -v第一条输出里的 version 和第二条里的 JVM 必须能对上。如果 Unity 里配的是自带 OpenJDK但系统 JAVA_HOME 指向另一个版本容易在命令行构建时串味。我的做法是干脆不在系统层配 JAVA_HOME全部交给 Unity 的 External Tools 管命令行只在排错时临时export JAVA_HOME...一下。Gradle 这边如果项目开了 Custom Gradle Template工程里会多出Assets/Plugins/Android/mainTemplate.gradle和gradleTemplate.properties。后者有几行是必配的# 打包内存SDK 依赖多的时候 2G 容易 OOM org.gradle.jvmargs-Xmx4096M -Dfile.encodingUTF-8 # 新版 Android 依赖基本都要求开启 android.useAndroidXtrue android.enableJetifiertrue # 关掉 R8 的完整模式减少混淆阶段跟 SDK 的冲突 android.enableR8.fullModefalsejvmargs给到 4096M 是因为 HMS 的 aar 加起来体积不小加上你自己的业务依赖2048M 在低配机器上大概率在中途 OOM报错信息还特别不直观只说Java heap space。enableJetifier打开会让构建变慢但能自动把老的 support 库转成 AndroidX接第三方 SDK 时省掉很多手工改包名的事。2.3 包名、签名、minSdkVersion三件必须提前定死的事包名一旦在 AGC 后台建了应用就不能改只能重建。所以第一步是把 Player Settings → Other Settings 里的 Package Name 定下来并且跟后台一个字一个字对上大小写都算。我见过有人后台填com.demo.hmsgame工程里写com.demo.HmsGame装上去登录回调永远不回来查了两天才发现是大小写。签名文件也要提前生成好不要等到最后出 release 包才想起来# 生成一个有效期 25 年的签名HMS 后台登记指纹要用 keytool -genkeypair -v \ -keystore hms-demo.keystore \ -alias hmsdemo \ -keyalg RSA \ -keysize 2048 \ -validity 9125参数含义-keysize 2048是 RSA 密钥长度低于 2048 有些平台会拒绝-validity 9125是 25 年应用市场上架普遍要求有效期覆盖到 2033 年以后写短了后面要换签名换签名等于换应用用户全部要重装。生成完把 keystore 文件和密码放在工程外面单独保管不要提交进 git。minSdkVersion 同样要提前统一。HMS 各 Kit 对最低版本有要求Unity 默认的 22 或 19 可能偏低报错形式是uses-sdk:minSdkVersion 19 cannot be smaller than version 21 declared in library。改法是在 Player Settings → Minimum API Level 抬到 21 或以上如果项目里有第三方 aar 声明了更高版本就按最高的那个来。这一步没做会在 Manifest 合并阶段直接失败而不是等到运行时报错反倒好排查。3. 导入 HMS SDK从 AGC 后台到 Unity 工程的落地动作环境定死之后接下来是按顺序落地文件。这里最容易犯的错是顺序颠倒——先把 unitypackage 导进工程再去后台建应用结果 json 文件拿回来不知道往哪放随手丢在 Assets 根目录运行起来提示配置缺失。我习惯的顺序是后台建应用 → 拿 json 和参数 → 导入插件 → 按插件菜单配置 → 改 Manifest 和 Gradle。3.1 在 AGC 建应用并下载 agconnect-services.json进 AGC 后台新建应用包名必须和 Unity 工程里完全一致。建完之后在「项目设置」里能拿到几个关键参数APP ID、API Key、Client Secret以及一个agconnect-services.json配置文件。这个 json 是整套接入的核心里面写了包名、APP ID、各 Kit 的开关状态SDK 启动时会读它。要注意的是json 是从后台下载的静态文件一旦你在后台改了包名、加了新的 Kit、或者换了签名指纹都得重新下载覆盖。很多「昨天还好好的今天就不行了」的情况都是后台改过配置但本地文件还是旧的。我的习惯是在工程根目录建一个HMSConfig/放原始文件每次覆盖前先比对一下修改时间。3.2 导入 unitypackage 与目录摆放下载下来的插件包一般是.unitypackage直接双击或者 Assets → Import Package 导入。导入后菜单栏会多出一个 HMS 或者 Huawei 的菜单项不同版本叫法略有差异。点进去的 Settings 面板会让你填 APP ID 和包名填完点保存插件会做两件事把配置写进Assets/Plugins/Android/下的对应文件以及尝试更新 AndroidManifest。json 文件的位置是这一步最容易出错的点。插件不同版本对这个文件的查找路径要求不完全一样有的认Assets/Plugins/Android/下的有的认工程根目录还有的要求放在Assets/顶层。判断方法很直接构建出 apk 之后解包看assets/目录里有没有这个 json没有就是位置错了。我第一次接的时候就是因为放错了一层目录包能装能开一调登录就返回空翻了两小时日志。导入之后确认工程里出现下面这些目录缺一个都建议重新导入Assets/Plugins/Android/下的 aar 与 AndroidManifest.xmlAssets/Huawei/或插件自带目录下的 C# 封装脚本Assets/Plugins/Android/assets/下的agconnect-services.json3.3 AndroidManifest 与 Gradle 模板的必改项Manifest 里需要补的是应用级元数据让 SDK 启动时能读到 APP ID 和 API Key。插件自动更新通常会写进去但没有的话要手工加application !-- APP ID 和 API Key 从 AGC 后台项目设置里复制注意 appid 前缀不能丢 -- meta-data android:namecom.huawei.hms.client.appid android:valueappid你的APP_ID / meta-data android:namecom.huawei.hms.client.api_key android:value你的API_KEY / /applicationandroid:value里那个appid前缀是固定格式少写这四个字符加等号SDK 解析时会当作非法值直接跳过表现为初始化返回失败但不告诉你原因。这一点文档里写得很小实际踩的人不少。Gradle 那边要在mainTemplate.gradle里加上 HMS 的依赖仓库否则构建时会报找不到com.huawei.agconnect系列包allprojects { repositories { google() mavenCentral() // HMS 依赖的仓库加在 google() 后面即可 maven { url https://developer.huawei.com/repo/ } } } dependencies { // 版本号从插件目录下的 README 或 AGC 后台的接入指引里复制不要凭记忆填 implementation com.huawei.agconnect:agconnect-core:版本号 implementation com.huawei.hms:base:版本号 }仓库地址写错一个字符就是 404而 Gradle 的报错往往只显示「Could not find xxx」不会告诉你仓库地址不对得往上翻几屏看Could not resolve后面的 URL。另外allprojects块要放对位置有的模板本身已经有这个块直接追加maven行就行重复定义会导致模板冲突。如果项目开了Custom Main Gradle Template注意构建时代码里Assets/Plugins/Android/mainTemplate.gradle会覆盖默认模板改错了不会报错只会静默生效。改完之后建议做一次Assets → External Dependency Manager → Android Resolver → Force Resolve装了 EDM4U 的话让依赖重新拉一遍。4. 初始化与配置把 APP_ID、包名和回调一次配对文件放对只是及格线真正决定能不能跑通的是初始化时机和参数。HMS 的初始化是异步的回调没回来之前调任何 Kit 都可能返回未初始化错误。我见过最常见的写法是把初始化塞进第一个场景某个空物体的 Start 里结果场景切换太快的项目在登录界面弹出来的时候初始化还没完成表现就是登录按钮点了没反应。4.1 初始化调用时机为什么不能写在第一个场景的 Start 里正确做法是在游戏启动最早的入口调用一次并且保证调用对象跨场景不销毁。Unity 里通常用一个挂了DontDestroyOnLoad的引导脚本承担这个角色using UnityEngine; using Huawei.Hms.Agent; // 命名空间随插件版本略有差异以导入后的 API 为准 public class HmsBootstrap : MonoBehaviour { private static bool s_inited false; void Awake() { // 跨场景常驻避免切场景后回调丢失 DontDestroyOnLoad(gameObject); if (s_inited) return; // 防止重复初始化 s_inited true; // 初始化是异步的结果在回调里给出 HMSAgent.Init(OnInitResult); } private void OnInitResult(int retCode) { if (retCode 0) { Debug.Log([HMS] init success); // 只有这里返回成功后面的登录、推送、支付才可用 } else { Debug.LogError($[HMS] init failed, retCode{retCode}); } } }retCode 0表示成功非 0 的取值各家 Kit 含义不同文档里有对照表排错时先把 retCode 记下来再查比盲猜快得多。s_inited这个静态标记看着多余但热更新或者场景重载的场景下重复初始化会让 SDK 内部状态错乱表现是偶发回调不触发属于那种「玄学」级别的偶发问题。还有一点初始化失败不要直接抛异常阻断游戏。HMS 的很多能力是可选增强初始化失败时应该降级到自有账号体系或者游客模式而不是白屏。这个判断要写在业务层SDK 层不管。4.2 登录、推送、支付的最小可用配置每个 Kit 的接入都分三步Manifest 声明、初始化后调用、回调处理。以账号登录为例Manifest 里需要声明对应的 Activity插件导入时一般已经写好检查一下有没有被你的主 Manifest 覆盖掉。调用侧大致是这样// 登录是异步的回调里拿到 authCode再拿去自己的服务器换 token HMSAccount.Login((result) { if (result.IsSuccess) { // authCode 有时效性拿到后立刻上送服务端不要存在本地 string authCode result.AuthCode; Debug.Log($[HMS] login ok, code length{authCode?.Length}); } else { // 用户主动取消也会走这里要跟真正的失败区分开 Debug.LogWarning($[HMS] login failed, code{result.RetCode}); } });注意authCode不能当作用户标识长期保存它有过期时间正确流程是上送自己的服务端换 session。RetCode里用户取消和网络失败是不同值UI 上要区别对待取消不该弹错误提示。推送这块除了 Manifest 里声明服务还要确认后台的推送开关是打开的。测试阶段最容易忽略的是「测试设备」没登记导致后台发消息永远显示送达 0。支付则是必须先在后台配置商品和回调地址本地代码写对了但商品没上架调用一样会失败且失败码和参数错误长得差不多。4.3 release 包的混淆与签名配置debug 包一切正常、release 包登录失败几乎是每个接 SDK 的人都会遇到一次的经典剧情。原因通常是混淆把 SDK 的回调类或者反射用到的类名改了。解决办法是在proguard-user.txt里补规则# 保留 HMS 相关类避免混淆后回调找不到 -keep class com.huawei.** { *; } -keep class com.huawei.agconnect.** { *; } # 保留 Android 组件入口 -keep public class * extends android.app.Activity -keep public class * extends android.app.Service规则写完要确认构建时真的用上了这个文件Player Settings → Publishing Settings 里勾选Custom ProGuard File文件放到Assets/Plugins/Android/下。只建文件不勾选等于没写。签名这块release 用的 keystore 指纹必须登记到 AGC 后台。debug 和 release 用的签名不同很多人只在后台填了 debug 的指纹测试一切正常一上架就登录失败。把 SHA256 指纹也算出来一起填# 输出签名指纹把 SHA256 那行复制到 AGC 后台 keytool -list -v -keystore hms-demo.keystore -alias hmsdemo5. 排查记录五条最费时间的踩坑下面这五条是我在不同项目里真实耗过时间的按发生阶段排。写的时候尽量保留了当时的报错特征方便对照。5.1 构建阶段的三类报错现象一Could not find com.huawei.agconnect:agconnect-core。构建刚开始就失败提示解析不到依赖。原因基本只有两个mainTemplate.gradle里没加 HMS 的 maven 仓库或者仓库地址写错。解决是把maven { url https://developer.huawei.com/repo/ }加到allprojects.repositories里并且确认没被后面的仓库配置覆盖。Gradle 的仓库是有顺序的先找到就不再找所以 HMS 那段要放在google()之后、其它镜像之前。现象二Manifest merger failed提示 minSdkVersion 冲突。原因是某个 aar 声明了比你工程更高的最低版本。解决是把 Player Settings 里的 Minimum API Level 抬到冲突方要求的版本实在不能抬就在 Manifest 里加tools:replaceandroid:minSdkVersion但这是权宜之计抬版本才是正解。现象三Java heap space构建到一半 OOM。原因是 Gradle 默认堆内存太小HMS 的 aar 加上业务依赖后不够用。解决是改gradleTemplate.properties里的org.gradle.jvmargs-Xmx4096M。加到 4096 还不行多半是机器本身内存吃紧关掉几个 Chrome 标签页比继续加参数有效。5.2 运行阶段闪退与初始化失败现象四包能装上点开立刻闪退logcat 只有一行client info is null。原因是 SDK 启动时没读到agconnect-services.json或者读到了但包名对不上。解决分两步先用adb shell pm path 你的包名找到 apk 路径解包确认assets/下真的有这个 json再核对 json 里的package_name字段和工程里的 Package Name 是否完全一致包括大小写。我遇到过一次是构建缓存导致的Clean 之后重新构建就好了所以确认文件存在却没生效时先 Clean。现象五初始化一直不回调日志里没有任何 HMS 输出。原因是初始化调用的时机太早早于 SDK 内部依赖的某些 Android 组件完成注册或者是调用对象被销毁了。解决办法是把初始化从Start挪到Awake并挂DontDestroyOnLoad同时确认调用前没有其它代码先调用了 Kit 的接口。排查时用adb logcat -s HMSAgent:* HuaweiID:*过滤关键字能省掉大量翻日志的时间。5.3 上架与签名相关的两个坑release 包登录失败是最典型的签名问题。现象是 debug 包正常release 包装上后一切调用返回鉴权失败。原因就是后台没登记 release 签名的指纹。解决方法前面提过keytool -list -v拿到 SHA256 后填进后台然后重新下载agconnect-services.json覆盖到工程里——注意这一步不能省后台改了配置本地文件不更新等于没改。另一个坑是用了 V2 签名但没开 V1。部分机型上装 release 包会提示安装失败而不是运行失败很容易误判成包体损坏。解决方法是在 Publishing Settings 里同时勾选 V1 和 V2虽然 V1 已经过时但兼容性上留一道保险更省事。6. 装完怎么验证真机上跑通 HMS 的检查顺序验证这件事我吃过「在编辑器里看日志觉得没问题真机一装全是错」的亏。Unity 编辑器里跑的是 Mono 模拟环境HMS 的 aar 根本没加载所以任何在编辑器里的「成功」都不算数。必须出 apk装真机按顺序过一遍。第一步先看包体和配置有没有进对。用 adb 把 apk 拉出来解包确认assets/agconnect-services.json存在且内容是最新的# 找到已安装应用的实际路径并解包检查配置文件有没有打进去 adb shell pm path com.demo.hmsgame adb pull /data/app/.../base.apk ./check.apk unzip -l check.apk | grep agconnect第二步看初始化。启动应用后立刻抓日志只过滤 HMS 相关 tag避免被业务日志淹没adb logcat -c adb logcat -s HMSAgent:* AGConnect:* HuaweiID:*这一步的目标只有一个看到初始化成功的那行输出retCode为 0。看不到就回去查第 4 章和第 5 章不要往后走。第三步逐项验能力顺序是登录 → 推送 → 支付因为后者依赖前者的账号态。每一项都按「触发 → 回调 → 后台确认」三段验比如登录成功后再去后台看用户数有没有加 1支付成功后在后台看订单状态。只看客户端回调是不够的客户端成功服务端没收到的情况并不少见。最后整理一张自己的检查表每次出新包都过一遍检查项通过标准常见失败原因配置文件apk 内存在且为最新后台改配置未重新下载包名一致性工程与后台完全相同大小写不一致初始化日志 retCode 为 0时机太早或被销毁登录回调拿到 authCode 且服务端可换 token签名指纹未登记推送后台显示送达数大于 0测试设备未登记release 包与 debug 表现一致混淆规则缺失从那以后我每次接新的 SDK都会先用一个空工程跑通最小闭环再往业务工程里搬绝不在一个已经装了七八个插件的工程里做第一次接入——那种环境里出问题你连是哪个插件引起的都判断不了。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。