Unity Java Kotlin 交互

2 篇文章 0 订阅
1 篇文章 0 订阅

从Unity调用同伴对象内的Android Kotlin函数

这是一篇转载文章,为了记录Unity调用Kotlin的写法,原文地址:
https://www.5axxw.com/questions/content/dis5k1

我的科特林班

class MyAnalytics internal constructor(
    private val MyAnalyticsConfiguration: MyAnalyticsConfiguration
) : MyAnalyticsLogger {

    .
    .
    .

    override fun logEvent(eventRequest: Event?) {
        // some code in here
    }

    companion object {

        @JvmStatic
        fun factory(
            context: Context,
            MyAnalyticsConfiguration: MyAnalyticsConfiguration = MyAnalyticsConfiguration()
        ) : MyAnalytics {
            val eventExecutor = MyWorkManager(
                workManager = WorkManager.getInstance(context.applicationContext),
                MyAnalyticsConfiguration = MyAnalyticsConfiguration
            )
            return MyAnalytics(
                MyAnalyticsConfiguration
            )
        }
    }
}

我希望能够从我的Unity代码访问factory函数。
在科特林我可以这样做:

MyAnalytics.factory(
      context = requireActivity()
)

但我怎么能在Unity中做到这一点呢?这是我尝试过的。

AndroidJavaClass UnityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject UnityPlayerActivity = UnityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject myAnalytics = new AndroidJavaObject("com.test.analytics.MyAnalytics");
AndroidJavaObject analyticsObject = myAnalytics.Call<AndroidJavaObject>("factory", UnityPlayerActivity); //Also tried with 'CallStatic'; no result, same error

我收到的错误是:

AndroidJavaException:java.lang.NoSuchMethodError:
类Ljava.lang.Object中没有name='factory'signature='(Landroid.app.Application;)Ljava/lang/Object;'的静态方法;
12-1014:00:21.883 13537 13674 E Unity:java.lang.NoSuchMethodError:
类Ljava.lang.Object中没有name='factory'signature='(Landroid.app.Application;)Ljava/lang/Object;'的静态方法;
12-1014:00:21.883 13537 13674 E Unity:atcom.unity3d.player.ReflectionHelper.getMethodID(Unknown资料来源:162)
12-1014:00:21.883 13537 13674 E Unity:在com.unity3d.player.UnityPlayer.nativeRender(Native方法)
12-1014:00:21.883 13537 13674 E Unity:在com.unity3d.player.UnityPlayer.access$300(Unknown来源:0){10237@1027@1367}统一资料来源:95)
12-1014:00:21.883 13537 13674 E Unity:在android.os.Handler.dispatchMessage(Handler.java:10312-1014:00:21.883 13537 13674 E Unity:在android.os.Looper.loop(Looper.java:21412-1014:00:21.883 13537 13674 E Unity:在com.unity3d.player.UnityPlayer$e.run(Unknown资料来源:20)

查看反编译代码

为了理解实现中的问题,您需要将Kotlin代码反编译为Java代码,并基于Java代码而不是Kotlin实现Unity部分。

让我们举一个Kotlin代码的简单示例,它将打印日志,仅此而已:

class MyKotlinClass(val name: String = "DEFAULT NAME") {
    fun callNormalFunc() {
        Log.d("UNITY", "callNormalFunc from Kotlin code")
    }
    companion object {
        @JvmStatic
        fun callStaticCompanionFunc(): MyKotlinClass {
            Log.d("UNITY", "callStaticCompanionFunc from Kotlin code")
            return MyKotlinClass("NEW NAME")
        }
    }
}

反编译的Java代码如下:

public final class MyKotlinClass {
   @NotNull
   private final String name;
   @NotNull
   public static final MyKotlinClass.Companion Companion = new MyKotlinClass.Companion((DefaultConstructorMarker)null);

   public final void callNormalFunc() {
      Log.d("UNITY", "callNormalFunc from Kotlin code");
   }

   @NotNull
   public final String getName() {
      return this.name;
   }

   public MyKotlinClass(@NotNull String name) {
      Intrinsics.checkNotNullParameter(name, "name");
      super();
      this.name = name;
   }

   // $FF: synthetic method
   public MyKotlinClass(String var1, int var2, DefaultConstructorMarker var3) {
      if ((var2 & 1) != 0) {
         var1 = "DEFAULT NAME";
      }

      this(var1);
   }

   public MyKotlinClass() {
      this((String)null, 1, (DefaultConstructorMarker)null);
   }

   @JvmStatic
   @NotNull
   public static final MyKotlinClass callStaticCompanionFunc() {
      return Companion.callStaticCompanionFunc();
   }

   public static final class Companion {
      @JvmStatic
      @NotNull
      public final MyKotlinClass callStaticCompanionFunc() {
         Log.d("UNITY", "callStaticCompanionFunc from Kotlin code");
         return new MyKotlinClass("NEW NAME");
      }

      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

从反编译的代码中我们可以看到,实际上我们可以用两种方式调用标记为@JvmStatic的函数。第一个直接来自我们的对象,第二个使用Companion对象。

Unity调用的方式

使用此调用的Unity代码如下所示:

public class KotlinCallScript : MonoBehaviour {

    private AndroidJavaObject _object;
    private AndroidJavaClass _staticClass;
    // Start is called before the first frame update
    private void Start () {
        _object = new AndroidJavaObject ("com.hardartcore.kotlin.MyKotlinClass");
        _staticClass = new AndroidJavaClass ("com.hardartcore.kotlin.MyKotlinClass");
        var defaultName = _object.Call<string> ("getName");
        Debug.Log ("START GET DEFAUL NAME: " + defaultName);
    }

    public void CallNormalFunction () {
        _object.Call ("callNormalFunc");
    }

    public void CallStaticFunction () {
        var companionObject = _staticClass.GetStatic<AndroidJavaObject> ("Companion");
        var newName = companionObject.Call<AndroidJavaObject> ("callStaticCompanionFunc").Call<string> ("getName");
        Debug.Log ("CALL STATIC FUNCTION NEW NAME: " + newName);
    }

    public void CallSecondWay () {
        var kotlinObject = _object.CallStatic<AndroidJavaObject> ("callStaticCompanionFunc");
        var newName = kotlinObject.Call<string> ("getName");
        Debug.Log ("CALL SECOND WAY NEW NAME: " + newName);
    }

}

你会选择哪种方式取决于你!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是关于UnityJava前后端交互的文档内容示例: 1. 引 - 介绍文档的目和范围,说明UnityJava前后端交互的重要性和意义。 2.术选择 - 解释为什么选择使用Java作为后端语言,并说明UnityJava交互的方式和原理。 3. 后端搭建 - 详细描述如何搭建Java后端环境,包括安装Java开发工具、配置开发环境、启动服务等。 4. 接口设计 - 定义前后端接口的数据格式和协议,如JSON、XML等。说明接口的参数、返回值和可能的错误码。 5. Unity集成 - 介绍如何在Unity中集成Java后端,包括添加相关依赖库、配置网络请求、处理数据传输等。 6. 数据交互 - 示范如何在Unity中向Java后端发送请求并获取响应。包括使用HTTP协议、WebSocket或其他通信方式。 7. 用户认证 - 解释如何在前后端交互中实现用户认证和授权功能,保证数据安全性。 8. 异常处理 - 讨论前后端交互中可能出现的异常情况,并提供相应的异常处理机制。 9. 性能优化 - 提供一些建议和技巧,以优化前后端交互的性能,包括网络请求的批量处理、数据压缩、缓存等。 10. 安全性 - 强调前后端交互中的安全性问题,如数据加密、防止XSS、CSRF等攻击。 11. 测试与调试 - 介绍如何进行前后端交互的测试和调试,包括单元测试、集成测试、接口调试等。 12. 部署与运维 - 提供部署和运维UnityJava前后端交互的建议,包括服务器配置、日志管理、监控等。 13. 参考资料 - 列出用于设计和实施UnityJava前后端交互的参考资料,如文档、教程、案例等。 这些内容是文档中常见的部分,具体的文档内容可能会根据项目需求和实际情况进行调整和扩展。在编写文档时,应该清晰、准确地描述UnityJava前后端交互的步骤和技术细节,以便团队成员理解和实施。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值