资讯动态

Unity调用Android原生入门:从零跑通第一个桥接方法

发布时间:2026/10/18 13:37:29 来源:尧图企业网站定制
简介这份工具集面向希望打通 Unity 与原生安卓交互的开发者尤其适合刚接触 JNI 与 Android 插件封装、需要快速上手的中级学习者。内容围绕 UnityActivity、UnityAppContext、PackageManager、RunOnUIThread 等基础方法展开并覆盖 Toast、Log 提示以及 Java 与 C# 字符串互转等常用桥接能力同时整理了获取 App 列表、判断服务与应用是否运行、打开/安装/卸载 App、发送广播以及读取 WiFi 状态、安卓版本、原生类型 ID 和内置 SD 卡路径等实用封装。资源共 45 个文件以 cs 脚本、asset 配置、meta 与 xml 清单为主另含 jar 包和 unity 场景压缩包约 48KB结构紧凑便于直接导入工程参考。目前已有 743 人学习适合作为 Unity 调用原生安卓的入门对照与二次封装起点。1. 先别被“原生”吓到Unity 调 Android 到底在调什么如果你刚开始用 Unity 做安卓项目大概率会遇到一个很具体的困惑游戏逻辑跑得好好的一旦要接支付、拿系统电量、调震动、读剪贴板、拉起某个系统设置页就突然卡住了。Unity 自己那套 API 覆盖不到这些系统层面的能力于是你搜到了“Unity 调用原生安卓”这个词。听起来像要同时精通两套完全不同的技术其实入门阶段你只需要搞懂一件事Unity 负责画面和逻辑安卓原生负责跟系统打交道两者之间开一扇门互相递东西。这扇门就是入门要学的全部核心。你可以把它想成一家餐厅Unity 是前厅负责接待客人、点单、上菜安卓原生是后厨负责处理只有后厨才有的设备。前厅服务员不会自己炒菜但他知道怎么把订单递进窗口也知道怎么把菜端出来。你要学的不是炒菜而是“递订单”和“端菜”这两个动作。这份入门参考工具集就是帮你把这套递送流程跑通的最小集合适合完全没碰过安卓原生、但已经会用 Unity 做基础项目的新手。2. 为什么值得学三个你迟早会撞上的场景2.1 场景一Unity 商店里找不到的系统能力Unity 的跨平台能力很强但它为了保持各平台一致主动放弃了很多“只有某个系统才有”的功能。比如你想让手机在特定时刻震动一下Unity 有Handheld.Vibrate()但它只能做最基础的震动时长、强度、节奏都控制不了。再比如你想读取当前设备的电量百分比Unity 根本没有对应 API。这些缺口不是 Unity 做得不好而是它故意不做的——它不想为每个平台都维护一套系统级接口。这时候你只有两条路要么去 Asset Store 找一个别人封装好的插件要么自己写一小段安卓代码通过 Unity 提供的桥接机制调用。前者省事但受制于人后者入门一次、终身受用。我刚开始学的时候也觉得“自己写原生”是遥不可及的事后来发现入门只需要理解三个文件之间的关系后面都是重复这个模式。2.2 场景二接第三方 SDK 时绕不开的桥做安卓项目迟早要接第三方 SDK比如广告、统计、登录、支付。这些 SDK 几乎都只提供安卓原生接口文档里全是 Java 或 Kotlin 代码。Unity 官方虽然有一些封装好的包但版本更新慢遇到问题很难排查。如果你懂一点 Unity 调原生的基础就能自己写一层薄薄的桥接把 SDK 的能力暴露给 Unity 的 C# 脚本。这层桥接不需要你成为安卓专家。入门阶段你只需要会写一个静态方法接收几个参数返回一个结果。剩下的复杂逻辑SDK 自己会处理。很多新手卡住不是因为技术难而是因为不知道“从哪里开始改”。这份工具集的价值就在于它把“从哪里开始”这件事给你标出来了。2.3 场景三性能敏感操作需要绕开 Unity 层有些操作在 Unity 层做会非常慢比如大量文件读写、复杂图像处理、加密解密。这些操作如果放到安卓原生层用 Java 或 Kotlin 实现再通过桥接把结果传回 Unity性能会好很多。入门阶段你不需要优化性能但你需要知道“这条路是通的”。等你以后遇到性能瓶颈至少知道有一个方向可以尝试而不是对着 Unity Profiler 干瞪眼。提示入门阶段不要一上来就追求性能最优。先把“能调通”放在第一位跑通之后再考虑优化。3. 动手之前把环境这关先过了3.1 你需要准备的三样东西第一样是 Unity Hub 和任意一个 2021 LTS 或更新的 Unity 版本。版本不用太新LTS 版本最稳。第二样是 Android Build Support 模块在 Unity Hub 里安装编辑器时勾选上包括 SDK、NDK、OpenJDK 三件套。第三样是一个能打开安卓工程的编辑器推荐 Android Studio也可以用 VS Code 加安卓插件但 Android Studio 对新手更友好报错信息更清楚。这三样东西装好之后先别急着写代码。打开 Unity新建一个 3D 项目切换到 Android 平台点一下 Build确认能打出一个空的 APK。这一步看起来毫无意义但它能帮你排除 90% 的环境问题。我第一次学的时候跳过这一步结果后面调不通花了整整一个下午才发现是 NDK 路径没配好。血泪经验先让空项目跑起来再动桥接代码。3.2 理解三个文件夹的分工Unity 项目里跟安卓原生相关的文件主要放在三个地方。第一个是Assets/Plugins/Android这里放编译好的.aar包或者.jar包Unity 打包时会自动把它们塞进最终的 APK。第二个是Assets/Scripts这里放你的 C# 脚本负责调用原生方法。第三个是安卓工程本身通常你会在 Android Studio 里单独建一个模块写 Java 或 Kotlin 代码编译成.aar后放回第一个文件夹。入门阶段你不需要同时维护三个文件夹。最简单的做法是先在 Android Studio 里写一个极简的安卓库编译出.aar拖进 Unity然后在 C# 里调用。这个流程走通一次后面就是复制粘贴改方法名的事。3.3 第一个能跑通的例子让安卓原生返回一个字符串下面这个例子不接任何 SDK不碰任何系统权限只做一件事Unity 调用安卓原生方法原生返回一个字符串Unity 打印出来。麻雀虽小五脏俱全桥接的完整链路都在里面。先在 Android Studio 里新建一个 Empty Activity 项目然后新建一个 Java 类package com.example.myplugin; public class MyPlugin { // 静态方法Unity 通过类名和方法名直接调用 public static String getMessage() { return Hello from Android Native; } }这段代码里package是包名后面 Unity 调用时要对应上。public static是必须的Unity 只能调用静态方法。方法返回一个字符串没有参数这是最简单的形式。编译出.aar文件把它放到Assets/Plugins/Android目录下。然后在 Unity 里新建一个 C# 脚本using UnityEngine; public class NativeBridge : MonoBehaviour { void Start() { // 获取安卓原生类参数是包名加类名 using (AndroidJavaClass pluginClass new AndroidJavaClass(com.example.myplugin.MyPlugin)) { // 调用静态方法返回值是字符串 string message pluginClass.CallStaticstring(getMessage); Debug.Log(原生返回 message); } } }AndroidJavaClass是 Unity 提供的桥接类构造参数必须是完整的包名加类名。CallStaticstring表示调用一个静态方法并且返回值是字符串。如果方法没有返回值就用CallStatic不带泛型。把脚本挂到场景里任意一个物体上打包到安卓手机运行Logcat 里就能看到那行输出。注意这段代码只能在安卓真机或模拟器上运行在 Unity 编辑器里会报错。调试时要么打包看 Logcat要么在 C# 里加平台判断编辑器里跳过调用。4. 避坑指南新手最容易翻车的五个地方4.1 坑一类名或包名写错报 ClassNotFoundException现象是运行时报ClassNotFoundException或者 Unity 控制台直接红字。原因通常是AndroidJavaClass里的字符串跟 Java 文件里的package和类名不一致。比如 Java 里写的是com.example.myplugin.MyPluginC# 里写成了com.example.MyPlugin大小写差一个字母就找不到。解决办法是复制粘贴不要手敲。从 Java 文件第一行的package开始复制加上类名直接粘到 C# 里。改完之后重新打包不要只在编辑器里试。4.2 坑二方法不是静态的调用直接崩现象是调用时抛出异常提示方法不存在或者参数不匹配。原因是 Unity 的CallStatic只能调用静态方法。如果你的 Java 方法忘了加staticUnity 就找不到它。入门阶段所有给 Unity 调用的方法都写成public static不要用实例方法。解决办法是检查 Java 方法签名确保有public static。如果确实需要实例方法得先创建对象但入门阶段不建议这么做容易把自己绕进去。4.3 坑三参数类型对不上传进去变成乱码现象是方法能调用但传过去的字符串变成乱码或者数字变成奇怪的值。原因是 C# 和 Java 的类型系统不完全一样比如 C# 的int对应 Java 的int没问题但 C# 的string传到 Java 里需要用AndroidJavaObject包装不能直接传。解决办法是入门阶段只传基本类型int、float、bool、string。字符串直接传通常没问题但如果遇到乱码检查编码格式确保两边都是 UTF-8。复杂对象先不要碰。4.4 坑四忘了在 AndroidManifest 里加权限现象是调用某个系统功能时直接闪退Logcat 里提示Permission Denied。原因是安卓系统对敏感操作需要声明权限比如读通讯录、访问相机、获取位置。Unity 打包时会生成一个默认的AndroidManifest.xml但不会自动帮你加权限。解决办法是在Assets/Plugins/Android下新建一个AndroidManifest.xml把需要的权限加进去。入门阶段先不要碰需要权限的功能从震动、剪贴板、电量这些不需要权限的开始。4.5 坑五在编辑器里测试原生调用现象是 Unity 编辑器里点运行直接报错说找不到安卓类。原因是AndroidJavaClass只在安卓运行时存在编辑器是 Windows 或 Mac 环境根本没有安卓虚拟机。这是新手最容易郁闷的地方因为编辑器里测试最快但偏偏测不了。解决办法是养成习惯写原生调用时先用#if UNITY_ANDROID !UNITY_EDITOR包起来编辑器里走一个模拟分支真机上走原生分支。这样编辑器里不会报错真机上也能正常调。void Start() { #if UNITY_ANDROID !UNITY_EDITOR using (AndroidJavaClass pluginClass new AndroidJavaClass(com.example.myplugin.MyPlugin)) { string message pluginClass.CallStaticstring(getMessage); Debug.Log(原生返回 message); } #else Debug.Log(编辑器环境跳过原生调用); #endif }这段代码在编辑器里打印“跳过”在真机上打印原生返回的字符串。平台判断是入门阶段必须养成的习惯能帮你省下大量排查时间。5. 下一步学什么从跑通一个方法到能接一个 SDK跑通上面那个返回字符串的例子之后你已经跨过了最难的门槛。接下来不要急着学复杂的东西按这个顺序往下走每一步都只比上一步多一点点。第一步把返回值从字符串换成整数再从整数换成布尔值。感受一下CallStaticint和CallStaticbool的写法差异。第二步给 Java 方法加上参数比如传一个整数进去返回整数加一。感受参数怎么从 C# 传到 Java。第三步写一个没有返回值的方法比如让安卓原生弹一个 Toast 提示。感受CallStatic不带泛型的写法。第四步把这三个方法合并到一个类里编译一次.aar在 Unity 里依次调用。这一步走完你就掌握了桥接的基本模式。再往后你可以尝试接一个真实的 SDK。选一个最简单的比如只提供初始化、展示、回调三个接口的广告 SDK。先写一个 Java 类把 SDK 的方法包一层静态方法编译成.aar再在 C# 里调用。遇到回调怎么办入门阶段先用轮询C# 每隔几秒调一次 Java 的“获取状态”方法。等熟练了再学AndroidJavaProxy做真正的回调。下面这张表是我建议的练习顺序每一步都对应一个具体能力不要跳步步骤练习内容检验标准1无参数返回字符串真机 Logcat 能看到输出2带参数返回整数传入 1 返回 23无返回值弹 Toast真机屏幕弹出提示4合并到一个类一次编译三个方法都能调5接一个简单 SDK能初始化并拿到回调状态最后说一个我自己的习惯。从那以后我每次新建安卓桥接都强制先写一个ping方法不传参数只返回一个固定字符串。打包到真机确认这个字符串能打印出来再开始写真正的业务逻辑。这个习惯帮我排除了无数次“到底是桥接没通还是业务代码写错”的纠结。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑