通过C#实现的AndroidJavaObject在Unity中的怪异行为

Venxit at Axiom Studios

相当长的帖子接post而至。这相当复杂,需要一个曾经使用过Unity插件的人(创建它们,而不使用它们),而且我不希望被淘汰,因为会出现一些常见的搜索词。因此,请阅读全文。

因此,当我尝试通过Unity的AndroidJavaObject调用本机函数时,我一直遇到一个很奇怪的问题

过去我已经构建了本机插件,我试图消除我每次需要更新插件时都必须更新多个JAR的依赖。因此,我将许多本机Java代码从插件移到Unity本身。

具体来说,有一种方法可以直接从C#调用本机Android函数(即系统函数),而不是创建一个插件并在该插件中调用一个调用本机函数的函数。

例如,在前面,如果必须创建Toast,则必须用Java编写一些本机代码,导出插件,然后调用该函数。这些天来,您可以按如下方式直接从C#调用Toast.makeText

这是我打电话给敬酒的方式。

    public static void Toast (string text, int duration) {
        #if UNITY_ANDROID && !UNITY_EDITOR
        CreateActivity();

        activity.Call("runOnUiThread", new AndroidJavaRunnable ( () => {
            new AndroidJavaObject("android.widget.Toast", activity)
                .CallStatic<AndroidJavaObject>("makeText", activity, text, duration)
                    .Call("show");
        }) );
        #endif
    }

这是CreateActivity方法

private static void CreateActivity () {
    #if UNITY_ANDROID && !UNITY_EDITOR
    if(activity == null)
        activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").
            GetStatic<AndroidJavaObject>("currentActivity");
    #endif

}

这完美地工作。但是,当我尝试使用相同的方法创建AlertDialog时,得到了一个androidjavaexception java.lang.classnotfoundexception

这是相关的代码

public static void ShowAlert (string title, string message, string buttonText) {

    #if UNITY_ANDROID && !UNITY_EDITOR

    CreateActivity();

    activity.Call("runOnUiThread", new AndroidJavaRunnable ( () => {
        var builder = new AndroidJavaObject("android.app.AlertDialog.Builder", activity);
        ***//Exception happens in the above line***

        builder.Call<AndroidJavaObject>("setMessage", message)  
            .Call<AndroidJavaObject>("setTitle", title)
                .Call<AndroidJavaObject>("setCancelable", false)
                .Call<AndroidJavaObject>("setNeutralButton", buttonText)
                .Call("show");
    }) );
    #endif
}

我尝试过的

  1. 使用了android.support.v7.app.AlertDialog.Builder而不是android.app.AlertDialog.Builder
  2. 添加了对v7和v4的支持JAR(特别是android-support-v4android-support-v7-appcompat
  3. 尝试为Unity的JNI创建我自己的实现并调用它

以上所有方法均失败。(第三个,相当壮观)

现在,我也尝试了其他类,其中大多数类都可以工作(例如ProgressDialog,它是AlertDialog的子类),而这些类都可以工作!

在这一点上,我很沮丧,我无法想到某些功能正常工作而其他功能失败的有效原因。

任何想法表示赞赏。

编辑1:添加了LogCat

I/Unity: AndroidJavaException: java.lang.ClassNotFoundException: android.app.AlertDialog.Builder
                                            at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <filename unknown>:0 
                                            at UnityEngine.AndroidJNISafe.CallStaticObjectMethod (IntPtr clazz, IntPtr methodID, UnityEngine.jvalue[] args) [0x00000] in <filename unknown>:0 
                                            at UnityEngine.AndroidJavaObject._CallStatic[AndroidJavaObject] (System.String methodName, System.Object[] args) [0x00000] in <filename unknown>:0 
                                            at UnityEngine.AndroidJavaObject.CallStatic[AndroidJavaObject] (System.String methodName, System.Object[] args) [0x00000] in <filename unknown>:0 
                                            at UnityEngine.AndroidJavaObject.FindClass (System.String name) [0x00000] in <filename unknown>:0 
                                            at UnityEngine.AndroidJavaObject._AndroidJavaObject (System.String className, System.Object[] args) [0x00000] in <filename unknown>:0 
                                            at UnityEngine.AndroidJavaObject..ctor (System.String className, System.Object[] args) [0x00000] in <filename unknown>:0 
                                            at AndroidNative+<ShowAlert>c__AnonSto
保罗·简

您遇到的问题是AlertDialog.Builder是AlertDialog的嵌套类,并且通过反射(这是AndroidJavaObject试图做的)创建嵌套类需要Java中的语法稍有不同:

android.app.AlertDialog$Builder

您的代码中还有一些其他小错误(由于构造函数无法正常工作,您可能不知道):

  • setNeutralButton需要一个回调参数(可以为null)
  • show必须在AlertDialog本身而不是构建器上调用。

考虑到这些微小的更正,一个有效的代码示例如下所示:

public static void ShowAlert(string title, string message, string buttonText)
{
    CreateActivity();

    activity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
    {
        var builder = new AndroidJavaObject("android.app.AlertDialog$Builder", activity);

        builder.Call<AndroidJavaObject>("setMessage", message)
            .Call<AndroidJavaObject>("setTitle", title)
                .Call<AndroidJavaObject>("setCancelable", false)
                .Call<AndroidJavaObject>("setNeutralButton", buttonText, null)
                .Call<AndroidJavaObject>("create")
                .Call("show");
    }));
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章