gpt4 book ai didi

java - 统一: Call Android Kotlin Function Inside Companion Object from Unity

转载 作者:行者123 更新时间:2023-12-04 08:26:35 38 4
gpt4 key购买 nike

我是一名本地开发人员,并且是 Unity 的新手。我试图通过在 Kotlin 中编码,然后将我的代码用作 Unity 中的插件来发挥我的优势。我遇到的一个问题是我无法弄清楚如何引用伴随对象内部的函数。
这是我的 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
)
}
}
}
我希望能够访问 factory我的 Unity 代码中的函数。
在 Kotlin 我可以这样做,
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: no static method with name='factory' signature='(Landroid.app.Application;)Ljava/lang/Object;' in 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;' in 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 com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)

最佳答案

为了了解您的实现实际上有什么问题,您需要反编译您的 Kotlin代码到 Java编码并实现 Unity部分基于 Java代码,而不是 Kotlin .
让我们举一个简单的例子 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 代码如下所示:
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);
}

}
这取决于您喜欢哪种方式。
我的建议是查看您反编译的 Java 代码,将其发布在这里,以便我们了解它为什么不起作用。

关于java - 统一: Call Android Kotlin Function Inside Companion Object from Unity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65233973/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com