Unity与Android交互通信系列(1)

这篇具有很好参考价值的文章主要介绍了Unity与Android交互通信系列(1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  运行于Android平台的原生App直接调用Android接口,可以享受近水楼台先得月的优势,而使用Unity开发的Android应用App则像是二等公民,使用Android原生功能特性就要麻烦得多,比如WiFi、蓝牙等,特别是一些高级功能特性,Unity中没有完全覆盖,直接在Unity中开发显得力不从心,而且,Unity为适应跨平台开发部署需求,其引擎架构设计要复杂灵活得多,基于Unity引擎开发的App应用运行于独立的VM(Virtual Machine,虚拟机)中(采用IL2CPP后端编译的应用,运行时仍然需要虚拟机支持),这给App应用与Android原生系统代码的交互带来了困难。在实际应用开发中,基于Unity的App应用与底层的Android平台之间经常有交互需求,本系列我们主要学习Unity引擎与Android平台的交互通信。

(一) Android与Unity通信原理

  Unity引擎最大的优势和特点是一次制作、多端部署,极大的减轻了多平台游戏的开发和维护成本,而Unity引擎实现强大跨平台能力的基础是Mono / IL2CPP,Mono / IL2CPP是Unity引擎跨平台的核心和根本。

  在2001年,电信标准组织ECMA制定了一个与特定语言无关的跨体系结构的运行环境CLI(Common Language Infrastructure,公共语言基础)标准规范,只要使用规范定义的高级语言进行开发、应用程序符合CLI规范即可以确保在不同的计算机体系结构上实现跨平台运行。在此基础上,微软公司根据标准实现了.NET Framework公共语言运行时(Common Language Runtime,CLR),因此CLR是CLI的一个实现,.NET Framework即是一个运行于CLR基础上的框架,它支持C#、VB.NET、C++、Python等语言,但由于.NET Framework与Windows的深厚渊源,.NET Framework本身并不能跨平台。

  Mono则是Xamarin公司主导的另一个CLI实现,它通过内置C#语言编译器、CLR运行时和各类基础类库,可以使应用程序运行在Windows、Linux、FreeBSD、Android、iOS等各种平台上,因此,通过Mono能使用C#语言编写Android或iOS应用程序。在CLI规范中,高级语言并不是直接被编译成机器字节码,而是编译成中间语言(Intermediate Language,IL),这是一种介于高级言与机器字节码之间的与特定底层硬件无关的语言,在真正需要执行的时候,IL会被加载到Mono VM中[ Unity支持C#、Unity Script、Boo三种脚本开发语言,所有高级语言都会被编译成IL中间语言。],由VM动态的编译成机器码再执行(Just In Time,JIT编译),其执行过程如图1(a)图所示。
Unity与Android交互通信系列(1),unity,android,交互,android与Unity通信

图1 Mono编译运行代码与IL2CPP编译运行代码流程示意图
  通过Mono,Unity引擎能够将应用部署到各类不同的系统平台上,实现跨平台运行。但由于IL在Mono VM中运行,而Mono VM是与系统平台紧密相关的,无法实现跨平台,所以Unity需要维护各种平台数量众多的Mono VM,并且JIT编译方式也降低了应用程序的运行速度,因此,Unity引擎引入了IL2CPP后端编译方式,通过将IL重新编译成C++代码,再由各类平台的C++编译器直接编译成原生汇编代码(Ahead Of Time,AOT编译),从而提升代码执行效率,并可利用各平台的C++编译器执行编译期间的优化,但由于高级动态语言的特性,内存管理和回收仍然需要统一维护,即需要IL2CPP VM负责GC、线程等服务性工作,但此时IL2CPP VM不再负责IL加载和动态解析,维护VM的工作量大为降低。


  虽然IL2CPP最后是采用AOT方式直接编译成各平台原生机器码,但其继承了IL中间语言的机制,对上层语言几乎没有影响(因为C++是静态语言,采用AOT方式编译,JIT动态语言的一些特性将不再可用),但它也需要借助VM进行内存管理等工作,如图1(b)所示。Android原生应用采用Java语言编写,Java语言也是先编译为Bytecode IL中间语言,然后依赖Android上的dalvik / art虚拟机解释执行。所以Unity引擎与Android原生代码交互通信实际是两个VM之间的通信,如图2所示。虽然Unity代码与Android原生代码在不同的VM中执行,但它们都处于同一个进程中,因此可以共享数据。

Unity与Android交互通信系列(1),unity,android,交互,android与Unity通信

图2 Unity与Android交互通信示意图
  在图2中,Unity引擎通过UnityEngine提供的API调用Android方法,Android则借助于com.unity3d.player包提供的API调用Unity方法。通过这种方式,Unity引擎可以直接调用Android类及对象的方法,而Android则只能调用Unity中指定GameObject所挂载的脚本的方法,或者通过动态代理的方式调用Unity引擎中的方法。

  在执行层面,UnityEngine封装了AndroidJavaObject、AndroidJavaClass、AndroidJavaProxy类,通过这几个类就可以获取Android端静态类或者动态对象,从而可以执行其相应方法;Android则是通过Unity应用的mainActivity与C#代码通信[ 本节讲述的Unity与Android的交互通信实质上是指C#代码与Java代码、JAR包、AAR包、SO包的相互调用,但遵循习惯描述为Unity引擎与Android操作系统软件之间的通信。]。

  Activity是Android应用中最基本和最重要的组件之一,其作用类似于web中的page、winform中的form,因此,只有活跃的Activity才能响应输入,所以,Android代码首先要通过com.unity3d.player.UnityPlayer包下的currentActivity获取到活跃Activity,利用其与Unity代码通信。

(二) Unity直接调用Java代码

  Unity2018之后的版本统一使用Gradle进行Android端的编译、构建和打包,而Android Studio也使用Gradle进行编译、构建和打包,即它们都使用同一种编译构建工具,也即是Java代码与C#代码都可以在Unity中被正确的编译到Android端,这就为在Unity中直接使用Java与C#语言打下了基础。

  而且为方便映射Java数据结构,在UnityEngine类中还内置了若干封装好的类,其中最重要的类有:AndroidJavaClass、AndroidJavaObject、AndroidJavaProxy,这些类是进行Java端与C#端相互调用的基础。AndroidJavaClass是java.lang.Class类在Unity中的表达,主要用于类结构反射、获取类静态属性或者调用类静态方法,其公共方法如表1所示。

表1 AndroidJavaClass公共方法列表
公共方法 调用对象/属性类型 泛型方法 描述
Call 非静态 Call 调用对象非静态方法
CallStatic 静态 CallStatic 调用类静态方法
Get 非静态 Get 获取对象非静态属性
GetStatic 静态 GetStatic 获取类静态属性
Set 非静态 Set 设置对象的非静态属性
SetStatic 静态 SetStatic 设置类静态属性
GetRawClass - GetRawClass 获取原生Java类型的指针,用于JNI
GetRawObject - GetRawObject 获取原生Java对象的指针,用于JNI
Dispose - - IDisposable接口回调

  AndroidJavaObject是java.lang.Object类在Unity中的表达,而java.lang.Object类是Java中所有类的基类,因此其能接受所有的Java对象,其公共方法如表2所示。文章来源地址https://www.toymoban.com/news/detail-765554.html

表2 AndroidJavaObject公共方法列表
公共方法 调用对象/属性类型 泛型方法 描述
Call 非静态 Call 调用对象非静态方法
CallStatic 静态 CallStatic 调用类静态方法
Get 非静态 Get 获取对象非静态属性
GetStatic 静态 GetStatic 获取类静态属性
Set 非静态 Set 设置对象的非静态属性
SetStatic 静态 SetStatic 设置类静态属性
GetRawClass - GetRawClass 获取原生Java类型的指针,用于JNI
GetRawObject - GetRawObject 获取原生Java对象的指针,用于JNI
Dispose - - IDisposable接口回调
  通过表1和表2可以看到,这两个类公共方法完全一样,这就为开发者使用这两个类提供了完全一致的使用外观。 在使用中,通过AndroidJavaClass类的forName()方法、.class属性生成相应类的对象,由于Class类方法常用于反射,所以一般用于调用对应类的静态属性或者方法;AndroidJavaObject表示对象,通过其getClass()方法可以获取该对象的类型,所以一般用于调用对象的实例方法或者属性。例如有一个类com.davidwang.util,其有一个静态方法StaticMethod(),一个实例方法InstanceMethod(),则new AndroidJavaClass("com.davidwang.util").callstatic("StaticMethod")等同于调用util.StaticMethod();而new AndroidJavaObject("com.davidwang.util").call("InstanceMethod")等同于 new Util().InstanceMethod()。

到了这里,关于Unity与Android交互通信系列(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity3D】Unity与Android交互

            本文主要介绍 Unity 打包发布 Android apk 流程、基于 AndroidJavaObject(或 AndroidJavaClass)实现 Unity 调用 Java 代码、基于 UnityPlayer 实现 Java 调用 Unity 代码,官方介绍见→Android。         Unity 项目 C# 中获取平台的代码如下,需要引入 UnityEngine 命名空间。         Ru

    2024年02月07日
    浏览(44)
  • Unity与Android交互(4)——接入SDK

    【前言】 unity接入Android SDK有两种方式,一种是把Unity的工程导出google project的形式进行接入,另一种是通过把Android的工程做成Plugins的形式进行接入。我们接入SDK基本都是将SDK作为插件的形式接入的。 对我们接入SDK的人来说,SDK也是分等级的: 第一等级:只有so文件,这种

    2024年02月16日
    浏览(41)
  • Unity与Android交互(3)——需要了解的Andorid基础知识

    【前言】 在上一篇文章中只是说了如何实现unity和android交互的问题,要了解其中的原理还必须要先了解一些Android的基础知识,了解后也能搞清楚如何接入SDK或者写Native插件。 (以下只是简要介绍,详细的内容需要自己去看链接) 【Android四大组件】 Activitiy 它提供了一个窗口

    2024年02月10日
    浏览(44)
  • Unity与原生交互之AndroidStudio篇——Unity导出Android工程,导入AndroidStudio打包APK全流程

          unityLibrary: unity的功能库模块 , android工程用到的重要文件夹 launcher: unity的启动器模块,包含很少的java代码   直接Open unity导出的整个android项目,Launcher模块作为app启动模块  1.AS先New一个空项目:   Empty Activity 不能选择Language,默认为Kotlin语言  Empty Views Activity 可以选择

    2024年02月11日
    浏览(42)
  • 【unity与android的交互】移动游戏发布更安心!Unity安卓平台打包相关的常见参数全详解

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity基础实战 首先需要切换到安卓平台 step1 :打包前的基础参数的设置 step2:包名的设置需要勾选,必须要去设置的内容 打包后进行测

    2024年04月17日
    浏览(72)
  • Unity3D2020+导出Android工程中使用并交互

    , 目录 1,版本信息 2,前期准备 Unity方面: Android方面: 3,Android与Unity3D交互 unity2020+ android studio 2021 *不要用android studio 2020系列,存在不能导入Library的bug 1,先配置打包的一些必要要素,包括包名之类 2,修改打包选项,将其打包为Android工程  3,打包出来的工程如下,其中

    2023年04月08日
    浏览(60)
  • Unity3d使用Netcode实现Hololens、Android和Pc端通信

    在Unity3d中使用现有的Netcode/Mirror组件实现Hololens、Android和Pc端的三方通信,可以指定一平台为服务器端,其他的两平台多为客户端,不过通常是进行两个平台的通信即可。在这片文章中,可以实现平移、缩放以及旋转的同步 具体步骤如下: 版本:unity2020.3LTS、VS2019 一、配置

    2024年02月09日
    浏览(49)
  • Unity与Js通信交互

    目录 1.Js给Unity传递消息 2.Unity给Js传递消息 其中,__objectName__ 是场景中的对象名称;__methodName__ 是当前附加到该对象的脚本中的方法名称;__value__ 可以是字符串、数字,也可为空。   unityInstance在打包之后index.html的位置  在别的地方用unityInstance,要在图片红框位置后面打括号

    2024年02月03日
    浏览(26)
  • Unity3D开发之unity和js通信交互

    官方 方法分享:Unity - 手动:与浏览器脚本的交互 (unity3d.com) 首先需要写一个JS的脚本,主要是调用mergeInto();方法,第一个参数不用变,第二个参数就是JS的方法集合。写完之后将这个文件的后缀改为.jslib,放到Plugins文件夹中  Test  内容: 2.C#(挂在场景 任意物体上) 3.Uni

    2024年02月12日
    浏览(40)
  • 基于Unity+Vue3通信交互的WebGL项目发布实践

    问题背景 我们最近需要把unity开发的pc项目迁移到web端,因为unity支持发布webgl。所以按照以往的开发流程,都是项目开发完成就发布webgl部署到服务器。 突然有一天,测试人员提出说为什么我们做的网页跟别人的不太一样呢?具体看下面两张图: 1、unity使用ugui做的界面发布

    2024年04月17日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包