2016-03-05 69 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)。謝謝一堆。 –