简体   繁体   English

Unity:调用 Android Kotlin Function Inside Companion Z497031794414A552435F90151C

[英]Unity: Call Android Kotlin Function Inside Companion Object from Unity

I am a native developer and new to Unity.我是一名本地开发人员,并且是 Unity 的新手。 I am trying to play to my strengths by coding in Kotlin and then using my code as a plugin in Unity.我试图通过在 Kotlin 中编码,然后在 Unity 中将我的代码用作插件来发挥我的优势。 One issue I am running into is that I cannot figure out how to reference a function that is inside of a companion object.我遇到的一个问题是,我无法弄清楚如何引用一个 function,它位于配套的 object 内部。

Here is my Kotlin class这是我的 Kotlin class

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
            )
        }
    }
}

I want to be able to access the factory function from my Unity code.我希望能够从我的 Unity 代码访问factory function。

In Kotlin I can do so like this,在 Kotlin 我可以这样做,

MyAnalytics.factory(
      context = requireActivity()
)

But how can I do the same in Unity?但是我怎样才能在 Unity 中做同样的事情呢? Here is what I have tried.这是我尝试过的。


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

The error I am receiving is,我收到的错误是,

AndroidJavaException: java.lang.NoSuchMethodError: no static method with name='factory' signature='(Landroid.app.Application;)Ljava/lang/Object;' AndroidJavaException: java.lang.NoSuchMethodError: no static 方法 name='factory' signature='(Landroid.app.Application;)Ljava/lang/Object;' in class Ljava.lang.Object;在 class Ljava.lang.Object; 12-10 14:00:21.883 13537 13674 E Unity: java.lang.NoSuchMethodError: no static method with name='factory' signature='(Landroid.app.Application;)Ljava/lang/Object;' 12-10 14:00:21.883 13537 13674 E Unity: java.lang.NoSuchMethodError: no static method with name='factory' signature='/Objectlang.Application.;) in class Ljava.lang.Object;在 class Ljava.lang.Object; 12-10 14:00:21.883 13537 13674 E Unity: at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:162) 12-10 14:00:21.883 13537 13674 E Unity: at com.unity3d.player.UnityPlayer.nativeRender(Native Method) 12-10 14:00:21.883 13537 13674 E Unity: at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0) 12-10 14:00:21.883 13537 13674 E Unity: at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95) 12-10 14:00:21.883 13537 13674 E Unity: at android.os.Handler.dispatchMessage(Handler.java:103) 12-10 14:00:21.883 13537 13674 E Unity: at android.os.Looper.loop(Looper.java:214) 12-10 14:00:21.883 13537 13674 E Unity: at Z4D23 12-10 14:00:21.883 13537 13674 E Unity: at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:162) 12-10 14:00:21.883 13537 13674 E Unity: at com.unity3d.player.UnityPlayer 。 com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95) 12-10 14:00:21.883 13537 13674 E Unity: at android.os.Handler.dispatchMessage(Handler.java:103) 12-10 14统一:00:21.883 13537 13674 E 统一:在 android.os.Looper.loop(Looper.java:214) 12-10 14:0330:21.883 E2yy34:21.883 12-10 6D9A2D102C5FE6AD1C50DA4BEC50Z.unity3d.player.UnityPlayer$e.run(Unknown Source:20) 6D9A2D102C5FE6AD1C50DA4BEC50Z.unity3d.player.UnityPlayer$e.run(来源不明:20)

In order to understand what's wrong with your implementation actually you need to decompile your Kotlin code to Java code and implement the Unity part based on the Java code, not Kotlin . In order to understand what's wrong with your implementation actually you need to decompile your Kotlin code to Java code and implement the Unity part based on the Java code, not Kotlin .

Let's have a simple example of Kotlin code, which will print Logs, nothing more:让我们举一个简单的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")
        }
    }
}

And the decompiled Java code looks like this:而反编译出来的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();
      }
   }
}

As we can see from the decompiled code actually we can call the function marked as @JvmStatic in two ways.从反编译的代码中我们可以看出,实际上我们可以通过两种方式调用标记为@JvmStatic的function。 First directly from our object and second using the Companion object.首先直接来自我们的 object,其次使用Companion object。

Unity code this using this call will look like:使用此调用的 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);
    }

}

It's up to you which way you will prefer.这取决于您喜欢哪种方式。

My suggestion is to look at your decompiled Java code, post it here so we can understand why it's not working.我的建议是查看您反编译的 Java 代码,将其发布在这里,以便我们了解它为什么不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM