【发布时间】:2014-11-13 09:51:01
【问题描述】:
目前我正在尝试将字符串列表保存在 Android 的共享首选项存储中。我使用共享首选项,因此可以使用 Android 本身的 MultiSelectListPreference。保存价值不是问题,但也许是原因。当我尝试读取该值时,问题本身就开始了。在那一刻,Android 将 ArrayList 提供给 Xamarin 代码,Xamarin 应将其转换为 C# 列表。然后我得到以下 InvalidCastException:
[MonoDroid] UNHANDLED EXCEPTION:
[MonoDroid] System.InvalidCastException: Cannot cast from source type to destination type.
[MonoDroid] at (wrapper castclass) object.__castclass_with_cache (object,intptr,intptr) <0x00068>
[MonoDroid] at Android.Runtime.JavaSet`1<string>.FromJniHandle (intptr,Android.Runtime.JniHandleOwnership) <0x0008f>
[MonoDroid] at Android.Content.ISharedPreferencesInvoker.GetStringSet (string,System.Collections.Generic.ICollection`1<string>) <0x0015b>
[MonoDroid] at canvastix.MultiSelectListPreference.OnDialogClosed (bool) <0x0009f>
[MonoDroid] at Android.Preferences.DialogPreference.n_OnDialogClosed_Z (intptr,intptr,bool) <0x0003f>
[MonoDroid] at (wrapper dynamic-method) object.4bc48339-d8f3-443a-a584-0088f55fe375 (intptr,intptr,bool) <0x00043>
[mono]
[mono] Unhandled Exception:
[mono] System.InvalidCastException: Cannot cast from source type to destination type.
[mono] at (wrapper castclass) object:__castclass_with_cache (object,intptr,intptr)
[mono] at Android.Runtime.JavaSet`1[System.String].FromJniHandle (IntPtr handle, JniHandleOwnership transfer) [0x00000] in <filename unknown>:0
[mono] at Android.Content.ISharedPreferencesInvoker.GetStringSet (System.String key, ICollection`1 defValues) [0x00000] in <filename unknown>:0
[mono] at canvastix.MultiSelectListPreference.OnDialogClosed (Boolean positiveResult) [0x00000] in <filename unknown>:0
[mono] at Android.Preferences.DialogPreference.n_OnDialogClosed_Z (IntPtr jnienv, IntPtr native__this, Boolean positiveResult) [0x00000] in <filename unknown>:0
[mono] at (wrapper dynamic-method) object:4bc48339-d8f3-443a-a584-0088f55fe375 (intptr,intptr,bool)
[mono-rt] [ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidCastException: Cannot cast from source type to destination type.
[mono-rt] at (wrapper castclass) object:__castclass_with_cache (object,intptr,intptr)
[mono-rt] at Android.Runtime.JavaSet`1[System.String].FromJniHandle (IntPtr handle, JniHandleOwnership transfer) [0x00000] in <filename unknown>:0
[mono-rt] at Android.Content.ISharedPreferencesInvoker.GetStringSet (System.String key, ICollection`1 defValues) [0x00000] in <filename unknown>:0
[mono-rt] at canvastix.MultiSelectListPreference.OnDialogClosed (Boolean positiveResult) [0x00000] in <filename unknown>:0
[mono-rt] at Android.Preferences.DialogPreference.n_OnDialogClosed_Z (IntPtr jnienv, IntPtr native__this, Boolean positiveResult) [0x00000] in <filename unknown>:0
[mono-rt] at (wrapper dynamic-method) object:4bc48339-d8f3-443a-a584-0088f55fe375 (intptr,intptr,bool)
我使用以下代码来读取 Activity 中的值。没什么特别的:
Button button = FindViewById<Button> (Resource.Id.button);
button.Click += delegate {
//Read value
ISharedPreferences Prefs = PreferenceManager.GetDefaultSharedPreferences (this);
ICollection<String> list = Prefs.GetStringSet("list", new List<String>());
Toast.MakeText(this, "Total items: " + list.Count, ToastLength.Short).Show();
};
我使用以下代码在片段中显示 MultiSelectListPreference:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<MultiSelectListPreference
android:key="list"
android:entries="@array/Entries"
android:entryValues="@array/Values" />
</PreferenceScreen>
这是Activity的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment
class="XamarinBugReadStringsetPreference.MainFragment"
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Read and Show" />
</LinearLayout>
最后但并非最不重要的是,这些是列表的值:
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<string-array name="Entries">
<item>1</item>
<item>2</item>
</string-array>
<string-array name="Values">
<item>Item 1</item>
<item>Item 2</item>
</string-array>
</resources>
请随意尝试。在清单中,我将 minSdkVersion 设置为 15,将 targetSdkVersion 设置为 19。
一周后我告诉我,这一定是 Xamarin 中的一个错误。因此,如果您能找到一种解决方法,那也很好。
【问题讨论】:
-
您不能将 String-Collection 保存到共享首选项中,只能保存原始类型,如 String、int、boolean。
-
尝试将您的集合转换为一些字符串,例如 StringBuilder builder = new StringBuilder(); for(String s : arr) { builder.append(s); } 返回 builder.toString();
-
Xamarin 应该能够将 c# 字符串列表保存到 java 字符串列表中。问题是 MultiSelectListPreference 处理保存和检索方法,这意味着我必须覆盖几乎每一个方法才能使其工作。更不用说 Xamarin 的未来更新可能会破坏我的扩展课程。我宁愿使用标准的 MultiSelectListPreference。
-
为什么不把它转换成逗号分隔的值并保存呢?
标签: java c# android .net xamarin