当将text格式化类型转换为ISpannable或ISpanned时,发布InvalidCastException
本文关键字:ISpanned 发布 InvalidCastException ISpannable text 格式化 类型转换 当将 | 更新日期: 2023-09-27 17:54:51
这个问题是一样的,但它似乎没有回答为什么这个强制转换在发布模式下失败,但在调试模式下工作的问题。
Android文档指定:
返回TextView显示的文本。如果setext()被调用参数为BufferType。SPANNABLE或BufferType。可编辑的,你可以将此方法的返回值强制转换为Spannable或Editable,分别。注意:返回值的内容不能为修改。如果你想要一个可修改的,你应该自己制作一个副本第一。
如果我在调试中运行下面的代码,它可以工作,在发布中它抛出一个InvalidCastException
var editText = FindViewById<EditText>(Resource.Id.MyEditText);
editText.SetText("hello", TextView.BufferType.Spannable);
var myTextView = FindViewById<TextView>(Resource.Id.MyTextView);
try
{
ISpannable t21 = (ISpannable)editText.TextFormatted;
ISpanned t22 = (ISpanned)editText.TextFormatted;
}
catch (Exception exception)
{
myTextView.Text = exception.Message;
}
FATAL EXCEPTION: main
06-09 16:30:34.135 E/AndroidRuntime(31672): Process: App27.App27, PID: 31672
06-09 16:30:34.135 E/AndroidRuntime(31672): java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
06-09 16:30:34.135 E/AndroidRuntime(31672): Caused by: md52ce486a14f4bc06-09 16:30:34.135 E/AndroidRuntime(31672): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
06-09 16:30:34.135 E/AndroidRuntime(31672): at dalvik.system.NativeStart.main(Native Method)
06-09 16:30:34.135 E/AndroidRuntime(31672): Caused by: java.lang.reflect.InvocationTargetException
06-09 16:30:34.135 E/AndroidRuntime(31672): at java.lang.reflect.Method.invokeNative(Native Method)
06-09 16:30:34.135 E/AndroidRuntime(31672): at java.lang.reflect.Method.invoke(Method.java:515)
06-09 16:30:34.135 E/AndroidRuntime(31672): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
06-09 16:30:34.135 E/AndroidRuntime(31672): ... 2 more
06-09 16:30:34.135 E/AndroidRuntime(31672): Caused by: md52ce486a14f4bcd95899665e9d932190b.JavaProxyThrowable: System.InvalidCastException: Cannot cast from source type to destination type.
06-09 16:30:34.135 E/AndroidRuntime(31672): at App27.MainActivity.OnCreate (Android.OS.Bundle) [0x00074] in d:'Users'dbeattie'Documents'Visual Studio 2013'Projects'App27'App27'MainActivity.cs:29
06-09 16:30:34.135 E/AndroidRuntime(31672): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <IL 0x00013, 0x000ef>
06-09 16:30:34.135 E/AndroidRuntime(31672): at (wrapper dynamic-method) object.6917b467-8852-465b-9332-eaefa6fe6832 (intptr,intptr,intptr) <IL 0x00017, 0x00043>
版本信息:
Xamarin 3.11.590.0 (5160db7) Visual Studio扩展启用Xamarin的开发。iOS和Xamarin.Android.
Xamarin的。Android 5.1.3.1 (d419c934e6ce2113653ff4c40214e3a5d5a69440)Visual Studio插件:Xamarin.Android.
我能够重新创建您的问题。虽然我不能给你一个确切的解释为什么会发生这种情况,但我确实注意到了这一点。可能是Xamarin的bug。Android和/或链接器过于激进,正在做一些导致InvalidCastException的事情,这就是我所做的。
在我的发布配置中,我的链接器被设置为"仅SDK程序集"。发生了InvalidCastException。当我将链接器设置为"不链接"时,InvalidCastException没有发生。这使得它类似于调试配置,其中链接器被设置为"不链接"。
所以看起来链接器正在剥离需要的东西和/或错误是Xamarin.Android.
然而,我确实找到了一个既适用于调试也适用于发布的解决方案。由于ISpannable和ISpanned对象是java到java对象的桥梁,最终将实现java . lang。在转换这些对象时,我通常使用JavaCast<>。在转换c#对象时,我使用()或"as"关键字。在这种情况下,由于您正在尝试转换Java对象(包装器),那么正确的转换方法将是使用JavaCast<>,如下所示:
var editText = FindViewById<EditText>(Resource.Id.MyEditText);
editText.SetText("hello", TextView.BufferType.Spannable);
var myTextView = FindViewById<TextView>(Resource.Id.MyTextView);
try
{
ISpannable t21 = editText.TextFormatted.JavaCast<ISpannable>();
ISpanned t22 = editText.TextFormatted.JavaCast<ISpanned>();
}
catch (Exception exception)
{
myTextView.Text = exception.Message;
}
使用此方法适用于调试和发布配置,包括将链接器设置为"不链接"answers"仅SDK程序集"。
不管怎样,我可能会在http://bugzilla.xamarin.com上提交一个bug报告,让Xamarin的人知道。无论如何,我认为在这种情况下使用JavaCast<>(因为您正在转换java包装器)是在这种情况下转换的正确方法。