相当长的帖子。它相当复杂,需要曾经使用过Unity插件的人(创建它们,而不是使用它们),并且我不希望因为一些常见的搜索词出现而被投票。所以,请阅读整篇文章。
所以,当我尝试通过Unity AndroidJavaObject
调用本机函数时,我发现了一个相当奇怪的问题。我之前已经构建了本机插件,我尝试删除每次需要更新插件时必须更新多个JAR的依赖关系。所以,我将很多原生Java代码从插件转移到Unity本身。
具体来说,有一种直接从C#调用原生Android功能(即系统功能)的方法,而不是在调用本机函数的插件中创建插件和调用函数。
例如,早些时候,如果我必须创建Toast,我必须用Java编写一些本机代码,导出插件然后调用该函数。这些天,人们可以直接从C#调用Toast.makeText,如下所示。
以下是我如何致电Toast。
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
}
我尝试了什么
以上都失败了。 (第三个,相当壮观)
现在,我也尝试了其他类,其中大多数都工作(例如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 :(得分:3)
您遇到的问题是AlertDialog.Builder是AlertDialog的嵌套类,并且通过反射创建嵌套类(这是AndroidJavaObject尝试做的事情)需要稍微不同的语法在Java中:
android.app.AlertDialog$Builder
您的代码中还有其他一些小错误(您无法了解,因为您的构造函数不起作用):
考虑到这些微小的修正,工作代码示例如下所示:
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");
}));
}