我有一个MvxDialogFragment(Mvvmcross),当它关闭时,有时会导致致命错误。
班级:
namespace Keiser.IPS.Screen.Droid.Views
{
using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using Cirrious.MvvmCross.Binding.Droid.BindingContext;
using Cirrious.MvvmCross.Binding.Droid.Views;
using Cirrious.MvvmCross.Droid.Fragging.Fragments;
using Keiser.IPS.Screen.Core.ViewModels;
using System;
public class SettingsView : MvxDialogFragment
{
protected Android.Views.View InflatedView;
public bool IsOpen { get; protected set; }
public override Dialog OnCreateDialog(Bundle savedState)
{
base.EnsureBindingContextSet(savedState);
IsOpen = true;
SettingsViewModel.SystemSettingsEvent += GoToSystemSettings;
SettingsViewModel.OnUpdateEvent += DoingUpdate;
InflatedView = this.BindingInflate(Resource.Layout.SettingsView, null);
CheckDemoSection();
CheckLicenseSection();
CheckUpdateSection();
MvxSpinner languageSpinner = InflatedView.FindViewById<MvxSpinner>(Resource.Id.LanguageSpinner);
languageSpinner.Focusable = true;
languageSpinner.FocusableInTouchMode = true;
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(Activity, Resource.Style.Theme_Dialog);
alertDialogBuilder.SetTitle(SettingsViewModel.GetText("GeneralSettings"));
alertDialogBuilder.SetView(InflatedView);
alertDialogBuilder.SetNegativeButton(SettingsViewModel.GetText("Cancel"), delegate { Cancel(); });
alertDialogBuilder.SetPositiveButton(SettingsViewModel.GetText("Save"), delegate { Save(); });
return alertDialogBuilder.Create();
}
protected SettingsViewModel SettingsViewModel { get { return ViewModel as SettingsViewModel; } }
protected void Save()
{
SettingsViewModel.SaveSettings();
IsOpen = false;
}
protected void Cancel()
{
IsOpen = false;
}
public override void OnCancel(IDialogInterface dialog)
{
base.OnCancel(dialog);
Cancel();
}
protected void CheckLicenseSection()
{
if (!SettingsViewModel.ShowLicenseSection)
InflatedView.FindViewById<LinearLayout>(Resource.Id.SettingsContainer).RemoveView(InflatedView.FindViewById<LinearLayout>(Resource.Id.LicenseContainer));
}
protected void CheckDemoSection()
{
if (!SettingsViewModel.ShowDemoSection)
InflatedView.FindViewById<LinearLayout>(Resource.Id.SettingsContainer).RemoveView(InflatedView.FindViewById<TextView>(Resource.Id.DemoModeLabel));
else
InflatedView.FindViewById<TextView>(Resource.Id.DemoModeLabel).Text += ": " + SettingsViewModel.GetText("On");
}
protected void CheckUpdateSection()
{
if (!SettingsViewModel.SoftwareManagerService.SoftwareManager.UpdateAvailable)
InflatedView.FindViewById<LinearLayout>(Resource.Id.SettingsContainer).RemoveView(InflatedView.FindViewById<LinearLayout>(Resource.Id.UpdateContainer));
}
protected void GoToSystemSettings(object s, EventArgs e)
{
StartActivityForResult(new Intent(Android.Provider.Settings.ActionSettings, null), 0);
}
protected void DoingUpdate(object s, EventArgs e)
{
new AlertDialog.Builder(Activity).SetMessage(SettingsViewModel.GetText("UpdatingMessage")).Show();
}
}
}
查看被强制执行:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="5dp"
android:id="@+id/SettingsContainer">
<TextView
local:MvxLang="Text Language"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Mvx.MvxSpinner
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
local:MvxBind="ItemsSource Languages; SelectedItem Language"
android:id="@+id/LanguageSpinner" />
<TextView
local:MvxLang="Text Theme"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Mvx.MvxSpinner
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
local:MvxBind="ItemsSource Themes; SelectedItem Theme"
android:id="@+id/ThemeSpinner" />
<TextView
local:MvxLang="Text Legend"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Switch
local:MvxBind="Checked Legend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_marginBottom="11dp"
local:MvxLang="TextOn On; TextOff Off" />
<TextView
local:MvxLang="Text DemoMode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:id="@+id/DemoModeLabel" />
<TextView
local:MvxBind="Text SoftwareCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:id="@+id/CodeLabel" />
<TextView
local:MvxBind="Text SoftwareVersion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:id="@+id/VersionLabel" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:id="@+id/LicenseContainer">
<TextView
local:MvxLang="Text LicenseKey"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/LicenseKeyLabel" />
<EditText
local:MvxBind="Text LicenseKey; TextColor LicenseKeyColor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:id="@+id/SystemSettingsContainer">
<Button
local:MvxLang="Text SystemSettings"
local:MvxBind="Click GoToSystemSettings"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:id="@+id/UpdateContainer">
<Button
local:MvxLang="Text Update"
local:MvxBind="Click DoUpdateCommand; Enabled CanDoUpdate"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
堆栈跟踪:
02-12 07:14:52.504: E/mono-rt(21076): [ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: 'jobject' must not be IntPtr.Zero.
02-12 07:14:52.504: E/mono-rt(21076): Parameter name: jobject
02-12 07:14:52.504: E/mono-rt(21076): at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Android.Views.View.SetOnClickListener (IOnClickListener l) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Android.Views.View+<>c__AnonStorey7.<>m__0 (IOnClickListener __v) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Java.Interop.EventHelper.RemoveEventHandler[IOnClickListener,IOnClickListenerImplementor] (System.WeakReference& implementor, System.Func`2 empty, System.Action`1 unsetListener, System.Action`1 remove) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Android.Views.View.remove_Click (System.EventHandler value) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Binding.Droid.Target.MvxViewClickBinding.Dispose (Boolean isDisposing) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Binding.Bindings.MvxBinding.Dispose () [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.ClearTargetBinding () [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.Dispose (Boolean isDisposing) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Binding.Bindings.MvxBinding.Dispose () [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Binding.BindingContext.MvxBindingContext.ClearAllViewBindings () [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Binding.BindingContext.MvxBindingContext.ClearAllBindings () [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Droid.Fragging.Fragments.MvxBindingFragmentAdapter.HandleDestroyViewCalled (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise (System.EventHandler eventHandler, System.Object sender) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Cirrious.MvvmCross.Droid.Fragging.Fragments.EventSource.MvxEventSourceDialogFragment.OnDestroyView () [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Keiser.IPS.Screen.Droid.Views.SettingsView.OnDestroyView () [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at Android.Support.V4.App.Fragment.n_OnDestroyView (IntPtr jnienv, IntPtr native__this) [0x00000] in <filename unknown>:0
02-12 07:14:52.504: E/mono-rt(21076): at (wrapper dynamic-method) object:4bb261f4-79d8-4e2d-80ec-785ea7b637ce (intptr,intptr)
在我看来,MvxViewClickBinding.Dispose
方法正在删除事件处理程序,并且在该进程的某个时刻,对象正在消失?检查MvxViewClickBinding. Dispose
方法是否检查被触摸的对象是否仍然存在,这样我就会认为Android堆栈中的某个位置正在消失。
我已经打了几个星期了,所以如果你有建议,请告诉我!
我添加了在OnCreateDialog
方法中充气的视图。
我的意思有时候,对话框中的9次中有9次没有问题,但偶尔会导致应用程序崩溃。我已经看到它使用屏幕上的两个按钮崩溃,以及使用关闭对话框单击或后退按钮。
以下是VS 2013中的追踪:
02-13 03:22:37.084 W/InputEventReceiver(11572): Attempted to finish an input event but the input event receiver has already been disposed.
An unhandled exception occured.
如果我在OnDestroy
或OnClose
方法之后立即触发GC,我可以每次都这样做。
看起来MvxViewClickBinding.Dispose
方法非常简单,所以我不确定这是一个Mvx错误。这似乎是Android V4支持库中的一些内容。
以下是设备中的trace.txt文件:https://gist.github.com/bayssmekanique/af33048a94350a819f13