将 TextFormatted 转换为 ISpannable 或 ISpanned 时,InvalidCastException 在释放中 [英] InvalidCastException in release when casting TextFormatted to ISpannable or ISpanned

查看:20
本文介绍了将 TextFormatted 转换为 ISpannable 或 ISpanned 时,InvalidCastException 在释放中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是一样的,但不是't 似乎回答了为什么这个转换在发布模式下失败但在调试中工作的问题.

This question is the same but it doesn't seem to answer the question as to why this cast fails in release mode but works in debug.

Android 文档指定:

The Android docs specify:

返回 TextView 显示的文本.如果 setText() 被调用使用 BufferType.SPANNABLE 或 BufferType.EDITABLE 的参数,您可以将此方法的返回值转换为 Spannable 或 Editable,分别.注意:返回值的内容不应该是修改的.如果你想要一个可修改的,你应该制作自己的副本首先.

Return the text the TextView is displaying. If setText() was called with an argument of BufferType.SPANNABLE or BufferType.EDITABLE, you can cast the return value from this method to Spannable or Editable, respectively. Note: The content of the return value should not be modified. If you want a modifiable one, you should make your own copy first.

如果我在调试中运行以下它可以工作,在发布时它会抛出一个 InvalidCastException

If I run the following in debug it works, in release it throws an 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 3.11.590.0 (5160db7) Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android 5.1.3.1 (d419c934e6ce2113653ff4c40214e3a5d5a69440)用于支持 Xamarin.Android 开发的 Visual Studio 插件.

Xamarin.Android 5.1.3.1 (d419c934e6ce2113653ff4c40214e3a5d5a69440) Visual Studio plugin to enable development for Xamarin.Android.

推荐答案

我能够重新创建您的问题.虽然我无法确切地告诉您为什么会发生这种情况,但我确实注意到了这一点.这可能是 Xamarin.Android 中的错误和/或链接器过于激进并且做了一些导致 InvalidCastException 的事情,这就是我所做的.

I was able to re-create your issue. Though I can't give you a definitive as to exactly why this is happening, I did notice this. It may be either a bug in Xamarin.Android and/or the linker is being too aggressive and doing something that is causing the InvalidCastException here's what I've done.

在我的发布配置中,我的链接器设置为仅 SDK 程序集".InvalidCastException 发生了.当我将链接器设置为不链接"时,没有发生 InvalidCastException.这使它类似于链接器设置为不链接"的调试配置.

In my Release Configuration, my Linker was set to "SDK Assemblies Only". The InvalidCastException happened. When I set the Linker to "Don't Link", the InvalidCastException did not happen. This make it similar to the Debug configuration in where the Linker was set to "Don't Link".

所以看起来链接器正在剥离一些需要的东西和/或错误是 Xamarin.Android.

So it would appear that the Linker is stripping out something that is needed and/or a bug is Xamarin.Android.

但是,我确实找到了一个既适用于 Debug 又适用于 Release 的解决方案.由于ISpannable 和ISpanned 对象是Java 对象的Java 桥梁,最终将实现Java.Lang.Obj,因此我通常在投射这些对象时使用JavaCast<>.在转换 C# 对象时,我要么使用 () 要么使用as"关键字.在这种情况下,由于您尝试转换 Java 对象(包装器),那么正确的转换方法将使用 JavaCast<>,如下所示:

However, I did find a solution that works for both Debug as Release. Since ISpannable and ISpanned objects are java bridges to Java objects, and ultimately will implement Java.Lang.Obj, I usually use JavaCast<> when casting those objects. In casting C# objects, I either use the () or "as" keyword. In this case, since the you're trying to cast Java Objects(wrappers), then the proper casting method would to be use JavaCast<> like so:

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;
}

使用此方法适用于调试和发布配置,包括将链接器设置为不链接"和仅 SDK 程序集".

Using this method works for both the Debug and Release configuration, including setting the Linker to "Don't Link" and "SDK Assemblies Only".

无论哪种方式,我都可能会通过在 http://bugzilla.xamarin.com 上提交错误报告来让 Xamarin 人员知道.无论如何,我认为在这种情况下使用 JavaCast<> 是在这种情况下进行转换的正确方法.

Either way, I would probably let the Xamarin folks know by submitting a bug report on http://bugzilla.xamarin.com. Regardless, I think that using JavaCast<> in this case (since you are casting java wrappers) is the proper way to cast in this case.

这篇关于将 TextFormatted 转换为 ISpannable 或 ISpanned 时,InvalidCastException 在释放中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆