unity调用java_Unity 与 Android 互调用

本文介绍了在Unity项目中如何实现与Android的互调用,包括Unity调用Android的Java代码来访问系统功能,以及Android如何通过消息发送或接口回调方式调用Unity。文章详细讲解了两种集成方式,Unity使用aar/jar库和Unity导出gradle项目,并比较了它们的优缺点。此外,还提供了Unity调用Java的示例代码和Android调用Unity的两种方法:消息发送和接口调用,并讨论了在Android主线程中执行Unity回调的注意事项。
摘要由CSDN通过智能技术生成

Unity 项目中一些需要访问安卓操作系统的功能,比如获取电量,wifi 状态等,需要 Unity 启动安卓系统的 BroadcastReceiver 监听状态,并在状态更新后通知到 Unity 界面。这就需要一种 Unity 与 Android 互相调用的机制,直观地看就是 C# 与 Java 互相调用的方法。

有 Unity 与 Android 互相调用需求的项目需要在两个开发环境中同时进行,创建两个工程,这时就涉及到如何将两个工程连接起来,有两种方式来连接:

Android 工程生成 aar/jar 文件,复制到 Unity 工程中,最终使用 Unity 的 Build 机制生成 apk。

Unity 工程将所有内容和代码导出为一个 Android gradle 项目,然后使用 Android Studio 打开项目进行开发,最终使用 Android Studio 打包 apk。

对比一下两者的优缺点:

Unity 使用 jar/aar 库

Unity 导出 gradle 项目

Unity 与 Android 依赖性

Unity 只依赖 Android 库文件,分割清晰,需要同步的文件只有库文件

Android 依赖 Unity 导出的场景数据,需要同步的文件太多

开发调试速度

Android 库文件比较小,调试较快

Unity 工程较大,同步较慢,调试周期长

Build机制

Unity 内置的 Android Build 机制,类似于 eclipse 编译 Android 项目

Android Studio gradle

Build灵活性

较差,无法深度定制,库有依赖时需要将全部依赖显式拷贝到 Unity 工程中

非常自由,可以使用最新的 Android Build 机制

如何打包apk

Unity Build 机制直接打包

Android Studio 打包

本项目使用的是第一种方法,因为这个项目中 Unity 工程特别大,导出 Unity 工程的代价太大。但也遇到了库文件依赖问题,不过由于依赖项不是很多,可以手动解决。以下是解决思路:

运行 gradle task dependencies,可以在 “Gradle projects” 窗口中目标项目的 help 目录中找到,这个 task 会打印出树形结构的依赖关系。

将所有的依赖项单独下载到本地,放到 Unity 工程中。

从这两个步骤可以看出,如果依赖层次比较少、数量比较少,还是可以接受的,但如果有大量深层的依赖就会变得特别麻烦。

b5e3cfcdf081

查看依赖树

Unity 调用 Android

Unity官方文档说明需要通过Plugin的方式调用Java代码,但实际上不需要引入任何Plugin就可以调用Java代码。只是一般情况下需要调用的都是封装好的库,这时才需要将 jar 或者 aar 放到 Unity 项目中,然后通过 C# 来访问其中的内容。

jar 或者 aar 文件可以放在Unity任意目录下,为了方便管理,都放在了 Assets/Plugins/Android 目录下。

C# 调用 Java 方法,获取 Java 字段

C# 调用 Java 的底层原理是使用JNI调用,Unity已经提供了很方便的接口:

创建对象:C#中使用 AndroidJavaObject 类封装 Java 对象,new 一个 AndroidJavaObject 对象相当于调用对应的 Java 对象的构造函数。借助 C# 可变参数列表,可以给 Java 对象的构造函数传递任意数量的参数。

// 第一个参数是 Java 类的完整包名,剩下的其他参数会传递给构造方法。

AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");

调用对象方法:使用 AndroidJavaObject 类的 Call 方法,有泛型与非泛型的两个版本。

// 泛型版本,目的是指定返回值的类型

int hash = jo.Call("hashCode");

// 非泛型版本,处理返回值是void的情况。

jo.Call("aMethodReturnVoid"); // String中没有返回void的简单方法。。。

获取类,主要用于获取静态字段或调用静态方法,常用来获取 UnityPlayer。

// 传入类的完整包名

AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

获取静态字段,只有泛型版本,因为不会有void类型的字段。。。

AndroidJavaObject jo = jc.GetStatic("currentActivity");

设置字段、获取对象字段、调用静态方法的代码类似,略。

类型映射

调用 Java 方法时,直接将 C# 变量/常量 传递给 Java 方法,会自动处理 C# 类型到 Java 类型的转换。通过 C# 泛型,可以指定 Java 方法的返回值类型,也就是将 Java 类型转换为了 C# 类型。C# 类型与 Java 类型是可以自动转换的,规则如下:

Java 类型

C# 类型

基本类型,比如 int, boolean

对应的值类型 int, bool

String

string

数组

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值