Unity3d 当通过C实现时,Unity中AndroidJavaObject的奇怪行为#

Unity3d 当通过C实现时,Unity中AndroidJavaObject的奇怪行为#,unity3d,unity5,Unity3d,Unity5,接下来是一篇相当长的文章。它相当复杂,需要有人以前使用过Unity插件(创建插件,而不是使用插件),我不希望因为一些常见的搜索词出现而被否决。所以,请阅读整篇文章 所以,当我试图通过Unity的 我以前构建过本机插件,我试图消除每次需要更新插件时必须更新多个JAR的依赖性。因此,我将我的许多本地Java代码从插件迁移到Unity本身 具体来说,有一种直接从C#调用本机Android函数(即系统函数)的方法,而不是创建插件并在调用本机函数的插件中调用函数 例如,在前面,如果我必须创建一个,我必须用

接下来是一篇相当长的文章。它相当复杂,需要有人以前使用过Unity插件(创建插件,而不是使用插件),我不希望因为一些常见的搜索词出现而被否决。所以,请阅读整篇文章

所以,当我试图通过Unity的

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

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

例如,在前面,如果我必须创建一个,我必须用Java编写一些本机代码,导出插件,然后调用函数。如今,人们可以直接从C#打电话如下

下面是我如何呼吁大家干杯的

    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
    }
publicstaticvoidtoast(字符串文本,int持续时间){
#如果UNITY\u ANDROID&!UNITY\u编辑器
CreateActivity();
activity.Call(“runOnUiThread”,新的AndroidJavaRunnable(()=>{
新的AndroidJavaObject(“android.widget.Toast”,活动)
.CallStatic,我得到一个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
}
publicstaticvoidshowAlert(字符串标题、字符串消息、字符串按钮文本){
#如果UNITY\u ANDROID&!UNITY\u编辑器
CreateActivity();
activity.Call(“runOnUiThread”,新的AndroidJavaRunnable(()=>{
var builder=newandroidjavaobject(“android.app.AlertDialog.builder”,activity);
***//异常发生在上面的行中***
Call,这是AlertDialog的一个子类),这些都可以工作

在这一点上,我相当困惑,我想不出一个有效的理由,让某些功能工作,而其他功能失败

任何想法都很感激

编辑1:添加日志猫

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
I/Unity:AndroidJavaException:java.lang.ClassNotFoundException:android.app.AlertDialog.Builder
位于:0中的UnityEngine.AndroidJNISafe.CheckException()[0x00000]处
在:0中的UnityEngine.AndroidJNISafe.CallStaticObjectMethod(IntPtr clazz、IntPtr methodID、UnityEngine.jvalue[]args)[0x00000]处
在UnityEngine.AndroidJavaObject.\u调用静态[AndroidJavaObject](System.String方法名,System.Object[]args)[0x00000]中:0
在:0中的UnityEngine.AndroidJavaObject.CallStatic[AndroidJavaObject](System.String方法名,System.Object[]args)[0x00000]处
位于:0中的UnityEngine.AndroidJavaObject.FindClass(System.String名称)[0x00000]处
在UnityEngine.AndroidJavaObject.\u AndroidJavaObject(System.String类名,System.Object[]args)[0x00000]中:0
在:0中的UnityEngine.AndroidJavaObject..ctor(System.String类名,System.Object[]args)[0x00000]处
在AndroidNative+c_uAnonsto

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

android.app.AlertDialog$Builder
您的代码中还有其他一些小错误(您无法知道,因为您的构造函数不工作):

  • setNeutralButton需要回调参数(可以为null)
  • 必须在AlertDialog本身而不是生成器上调用show
考虑到这些微小的修正,工作代码示例如下所示:

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");
    }));
}
publicstaticvoidshowAlert(字符串标题、字符串消息、字符串按钮文本)
{
CreateActivity();
activity.Call(“runOnUiThread”,新的AndroidJavaRunnable(()=>
{
var builder=新的AndroidJavaObject(“android.app.AlertDialog$builder”,活动);
builder.Call(“setMessage”,message)
.调用(“设置标题”,标题)
.Call(“可设置取消”,false)
.Call(“setNeutralButton”,buttonText,null)
.调用(“创建”)
.打电话(“秀”);
}));
}

有趣的问题!触发ClassNotFoundException的是实际的android.app.AlertDialog.Builder类吗(即,不是应用的方法调用中使用的隐式类之一)?logcat摘录可能会提供有用的额外信息。如果您无法访问的任何其他类仍然无法使用此方法实例化,请将它们添加到您的问题中(或开始一个新问题)我会看看我是否能弄明白。能在整个Unity Android互操作过程中获得更多的文档真是太好了!哇。我不知道我怎么会错过这个。这不是我第一次使用嵌套类,现在我嘲笑自己说,“哦,你怎么会错过这个?”是的,我知道还有一些不一致的地方,我必须修正。为了这个问题,我拿出了一些代码(OnClickListeners)。非常感谢。
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");
    }));
}