2016-03-05 376 views
1

相当长的帖子如下。这非常复杂,需要一个曾经使用过Unity插件的人(创建它们,而不是使用它们),而且我不想因为一些常见的搜索词出现而降低投票率。所以,请阅读整篇文章。通过C#实现AndroidJavaObject时奇怪的行为通过C#实现

所以,我一直有一个相当奇怪的问题发生了,当我试图通过过去统一的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.AlertDial og.Builder
  2. 增加了对V7 &支持JAR文件V4(具体Android的支持-V4 & Android的支持-V7-程序兼容性
  3. 尝试创建自己的统一的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 
+0

有趣的问题!它是触发ClassNotFoundException的实际android.app.AlertDialog.Builder类(即,而不是应用方法调用中使用的隐式类之一)吗? logcat摘录可能会提供有用的额外信息。 –

回答

3

你碰到的问题,是AlertDialog.Builder是嵌套类AlertDialog的,并通过反射创建嵌套类(这是什么AndroidJavaObject正在努力做的),需要在Java的语法稍有不同:

android.app.AlertDialog$Builder 

有在你的代码中的一些其他微小的错误(你不能知道因为你的构造器不工作):

  • setNeutralButton需要一个回调参数(可以为null)
  • 秀上被称为在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"); 
    })); 
} 
+0

如果您无法访问的任何其他类仍然无法使用此方法实例化,请将它们添加到您的问题中(或者开始一个新问题),然后我会看看是否可以解决问题。在整个Unity-Android互操作过程中获得更多的文档是很好的! –

+1

哇。我不知道我是如何错过的。这不是我第一次使用嵌套类,现在我正在笑我自己,“哦,你怎么错过了?”是的,我知道我必须解决其余部分的不一致问题。为了解决这个问题,我拿出了一些代码(OnClickListeners)。谢谢一堆。 –