如何将JNI C#类传递给Java或处理这种情况?

twe*_*ypi 12 c# java java-native-interface unity-game-engine

我试图从C#调用Java方法,它从java中调用如下:

EgamePay.pay(thisActivity, payAlias, new EgamePayListener() {
            @Override
            public void paySuccess(String alias) {
            }

            @Override
            public void payFailed(String alias, int errorInt) {
            }

            @Override
            public void payCancel(String alias) {
            }
        });
Run Code Online (Sandbox Code Playgroud)

前两个参数都可以,但是如何在C#中传递EgamePayListner?简单地创建具有相同功能的C#类将无法正常工作......

这是我目前正在做的事情:

using (AndroidJavaClass jc = new AndroidJavaClass("cn.egame.terminal.smspay.EgamePay"))
        {
            System.IntPtr cls_Activity = AndroidJNI.FindClass("com/unity3d/player/UnityPlayer");
            System.IntPtr fid_Activity = AndroidJNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;");
            object[] p = { fid_Activity, "payAlias", new EgamePayListener() };
            jc.CallStatic("pay", p);
        }

..

 class EgamePayListener
    {
        public void paySucess(string alias)
        {
        }

        public void payFailed(string alians, int errorInt)
        {
        }

        public void payCancel(string alias)
        {
        }
    }
Run Code Online (Sandbox Code Playgroud)

显然这是错的,我怎么能处理这种情况,以便在这些函数被触发时我可以在C#land中得到通知?

one*_*cat 3

如果您处于 Unity3D 环境中,从 Java 本机代码与 Unity3D C# 脚本交互的更好方法是调用该方法UnitySendMessage。你可以在Java代码中调用这个方法,并且会向C#发送一条消息,这样你就可以得到在C#中执行的指定方法。

您可以在 Unity 场景中添加一个游戏对象并创建一个 MonoBehavior 脚本,其中包含这三个方法(paySucess(string message)、payFailed(string message) 和 payCancel(message))。然后将新创建的脚本附加到游戏对象(让我们假设该游戏对象的名称为“PayListener”),并确保执行 Java 代码时场景中存在游戏对象(您可以DontDestroyOnLoad 在 中调用游戏对象Awake,例如)。

然后,在您的 Java 代码中,只需编写如下内容:

EgamePay.pay(thisActivity, payAlias, new EgamePayListener() {
    @Override
    public void paySuccess(String alias) {
        com.unity3d.player.UnityPlayer.UnitySendMessage("PayListener","paySuccess", alias);
    }

    @Override
    public void payFailed(String alias, int errorInt) {
        com.unity3d.player.UnityPlayer.UnitySendMessage("PayListener","payFailed", alias + "#" + errorInt);
    }

    @Override
    public void payCancel(String alias) {
        com.unity3d.player.UnityPlayer.UnitySendMessage("PayListener","payCancel", alias);
    }
});
Run Code Online (Sandbox Code Playgroud)

如果没有类,它将阻止 java 文件成功构建com.unity3d.player.UnityPlayer。您可以找到该/Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/bin/classes.jar文件并将其添加为您的 java 项目的依赖库。然后您就可以构建、生成并使用新的 jar 文件,而不会出现错误。

由于该UnitySendMessage方法只能采用 1 个参数,因此您可能必须 payFailed通过策略连接结果别名和 errorInt,并在 Unity C# 端解析它。

通过使用新构建的 jar 文件并将其加载为 或AndroidJavaClassAndroidJavaObject当调用 Java 中的方法时,应该调用 PayListener 脚本中的相应方法。

有关使用 UnitySendMessage 的 Android 插件的文档,您可以在此处访问如何实现 Android JNI 插件的官方指南,在示例 3 中。