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

在前述文章中,已经使用了AndroidJavaProxy代理接口,本节我们将详细的介绍AndroidJavaProxy代理的用法。正如其名,AndroidJavaProxy是一个代理,它在Android端代码与Unity端代码交互中起一个桥接作用。其一般用法为在Java代码中定义接口(Interface),建立代码调用外观,然后在Unity端用C#实现Java代码定义的接口,在使用时,在C#代码中实例化实现接口的类并将该实例对象传递到Java端,Java端根据情况执行接口方法,回调C#中的实现逻辑。

下面通过一个实例进行演示。首先需要在Java端定义一个接口,ProxyExample.java文件代码如下:

java 复制代码
//5-1
//Java端代码
package com.davidwang.android2unity;

public  interface ProxyExample
{
    void OnFired(String msg);
}

然后,在C#端,通过AndroidJavaProxy代理实现该接口,在使用时将实现接口的类的实例传递到Java端,代码如下:

csharp 复制代码
//5-2
//C#端代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnityProxyExample : MonoBehaviour
{
    void Start()
    {
        using (AndroidJavaObject jo = new AndroidJavaObject("com.davidwang.android2unity.ProxyUseCase"))
        {
            var mCallbackListener = new SDKCallbackListener();
            // 调用Jar中的方法,并把new的值传进去
            jo.Call("Init", mCallbackListener);
        }
    }

    class SDKCallbackListener : AndroidJavaProxy
    {
        // 引用Jar中接口
        public SDKCallbackListener() : base("com.davidwang.android2unity.ProxyExample") { }

        //实现接口中的方法
        public void OnFired(string str)
        {
            Debug.Log("OnFired:" + str);
        }
    }
}

在代码5-2中,C#端实现了Java接口,接口中的方法必须为Public,方法签名与Java端完全一致。然后通过Java端的Init()方法将实现接口的实例对象传递到Java端,Java端使用方法代码如下:

java 复制代码
//5-3
//Java端代码,ProxyUseCase.java
package com.davidwang.android2unity;

public class ProxyUseCase {
    private  ProxyExample proxyExample;
    public void Init(ProxyExample proxyExample){
        this.proxyExample = proxyExample;
        try {
            java.lang.Thread.sleep(5000);
            EventCallback();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
    public void EventCallback(){
        proxyExample.OnFired("some event fired in Android ");
    }
}

在代码5-3中,EventCallback()方法本应该由Java端的其他事件触发,为演示简单,这里采用了延时触发方法。Java端通过调用其接口方法,实现了对C#端实例对象方法的调用。他们之间的关系示意图如图1所示。

图1 AndroidJavaProxy原理示意图   在C#端,通过实现Java端的接口,可以生成本地端的实例对象,这个实例对象在Mono / IL2CPP虚拟机内,然后通过调用Java端的方法将本地端的实例对象引用传递到Java端,因为实例对象实现了Java端的接口,所以Java端可以通过接口调用到实例对象的方法,本质上是通过引用调用Mono / IL2CPP虚拟机端的本地实例对象。所以AndroidJavaProxy代理实质上是在C#端与Java端建立了一个对象引用指针,通过这个指针可以指向实例对象,虽然这个实例对象存在于另一个虚拟机中。

本节中,我们采用另一种打包方式,将代码打包成Jar包。Jar包只包含编译后的class文件与清单文件,不包含图片布局等资源文件;aar包则包含所有相关的资源,class文件、清单文件、res资源文件等。所以如果只有类库文件时建议生成Jar包;如果还包含布局文件、图片、字体等资源文件时建议使用aar包。

在Android Studio中,类库的建立方法与Unity与Android交互通信系列(3)所述一致,不再赘述。点击展开app目录下的android2unity目录,双击鼠标打开该目录下的build.gradle文件,如图2所示。

图2 打开类库目录下的build.gradle文件   如图2所示,在打开的build.gradle文件中dependencies指令前添加一个task[ Task任务要作为一级指令,即不包含在其他编译指令之中。],task任务指令代码如下:

java 复制代码
//5-4
task makeJar(type: Copy) {
    //如果之前有编译打包,则删除原存在的jar包
    delete 'build/libs/andriod2unity.jar'
    //Android Studio默认打包路径
    from('build/intermediates/aar_main_jar/release/')
    //将打包后的文件复制到该目录下
    into('build/libs/')
    //include参数来设置过滤,我们只关心classes.jar包
    include('classes.jar')
    //重命名生成的jar包
    rename ('classes.jar', 'andriod2unity.jar')
}
makeJar.dependsOn(build)

编译Jar包时,鼠标点击task任务左侧的绿色三角形图标展开下拉菜单,单击鼠标选择"Run 'Android2Unity[makeJ...'"开始编译打包,如图3所示。

图3 编译生成Jar包

编译打包成功后,即可以在android2unity类库模块下的build/libs目录下找到生成的android2unity.jar包[ 根据Android Studio版本不同,有的版本不会生成libs目录,这时可以将Jar包生成到outputs目录中,即代码清单5-4中将Jar包生成的路径修改到build/outputs目录下。通过Task任务的方式还可同时生成aar包,该包区分debug、release版本,位于build/outputs/aar目录下]。与使用aar包一样,将该jar文件复制到Unity工程Assets/Plugins/Android目录或其子目录下,然后在Unity端将UnityProxyExample脚本挂载到场景中的任意对象上,连接手机,打包运行,即可看到正确的调用输出。

相关推荐
曙曙学编程2 分钟前
初级数据结构——树
android·java·数据结构
狸克先生2 小时前
如何用AI写小说(二):Gradio 超简单的网页前端交互
前端·人工智能·chatgpt·交互
闲暇部落2 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX4 小时前
Android 分区相关介绍
android
大白要努力!5 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee5 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood5 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-8 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen11 小时前
MTK Android12 user版本MtkLogger
android·framework
向宇it16 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎