Xamarin.Forms 从 Xamarin.Android 项目调用对话框抛出异常
Xamarin.Forms Calling Dialog from Xamarin.Android Project Throws an Exception
到目前为止,我一直在尝试使用 IoC 容器从我的 xamarin.forms 应用程序调用对话框警报,但我无法使用此代码在我的应用程序中显示警报:
我的 viewModel 中的代码:
await _dialogService.DisplayMessageAsync("ERROR", "There are errors on your form!", "Cancel", null);
在我的共享项目中,我有这个 DialogService,这是我从 viewModel 调用的服务:
public class DialogService : IDialogService
{
readonly IDialogService _dialogService;
public DialogService()
{
_dialogService = DependencyService.Get<IDialogService>();
}
public void CloseAllDialogs()
{
_dialogService.CloseAllDialogs();
}
public async Task DisplayMessageAsync(string title, string message, string buttonCancelName, Action callback)
{
await _dialogService.DisplayMessageAsync(title, message, buttonCancelName, callback);
}
public async Task DisplayMessageConfirmAsync(string title, string message, string buttonOkName, string buttonCancelName, Action<bool> callback)
{
await _dialogService.DisplayMessageConfirmAsync(title, message, buttonOkName, buttonCancelName, callback);
}
}
所以在我的 Xamarin.Android.XXXXX 我有我的 DialogService 的实现,它是从我的 DialogService 在我的共享项目中调用的,这是代码:
public class DialogService : IDialogService
{
List<AlertDialog> _openDialogs = new List<AlertDialog>();
public void CloseAllDialogs()
{
foreach (var dialog in _openDialogs)
{
dialog.Dismiss();
}
_openDialogs.Clear();
}
public async Task DisplayMessageAsync(string title, string message, string okButton, Action callback)
{
await Task.Run(() => Alert(title, message, okButton, callback));
}
public async Task DisplayMessageConfirmAsync(string title, string message, string okButton, string cancelButton, Action<bool> callback)
{
await Task.Run(() => AlertConfirm(title, message, okButton, cancelButton, callback));
}
bool Alert(string title, string content, string okButton, Action callback)
{
var activity = (Activity)Forms.Context;
//var activity = (Activity)Android.App.Application.Context;
var alert = new AlertDialog.Builder(Android.App.Application.Context);
//var alert = new AlertDialog.Builder(activity);
alert.SetTitle(title);
alert.SetMessage(content);
alert.SetNegativeButton(okButton, (sender, e) =>
{
if (!Equals(callback, null))
{
callback();
}
_openDialogs.Remove((AlertDialog)sender);
});
Device.BeginInvokeOnMainThread(() =>
{
AlertDialog dialog = alert.Show();
_openDialogs.Add(dialog);
dialog.SetCanceledOnTouchOutside(false);
dialog.SetCancelable(false);
});
return true;
}
bool AlertConfirm(string title, string content, string okButton, string cancelButton, Action<bool> callback)
{
var alert = new AlertDialog.Builder(Android.App.Application.Context);
alert.SetTitle(title);
alert.SetMessage(content);
alert.SetNegativeButton(cancelButton, (sender, e) =>
{
callback(false);
_openDialogs.Remove((AlertDialog)sender);
});
alert.SetPositiveButton(okButton, (sender, e) =>
{
callback(true);
_openDialogs.Remove((AlertDialog)sender);
});
Device.BeginInvokeOnMainThread(() =>
{
var dialog = alert.Show();
_openDialogs.Add(dialog);
dialog.SetCanceledOnTouchOutside(false);
dialog.SetCancelable(false);
});
return true;
}
}
因此,每当调用私有方法警报时,它都会抛出如下异常:
Unhandled Exception:
Android.Views.WindowManagerBadTokenException: Unable to add window --
token null is not valid; is your activity running?
如果我切换这行代码就可以更正:
var alert = new AlertDialog.Builder(Android.App.Application.Context);
对于这行代码:
var activity = (Activity)Forms.Context;
var alert = new AlertDialog.Builder(activity);
使用这个的问题我收到这样的 Xamarin.Forms 警告:
'Forms.Context' is obsolete: 'Context is obsolete as of version 2.5.
Please use a local context instead.'
而且我有点偏执,我不喜欢收到警告并尝试尽可能更新我的代码,所以,有人可以帮助我使这段代码工作而无需使用过时的代码。因为我找到了将 (Activity)Forms.Context 替换为 Android.App.Application.Context 的答案,但在这种情况下它根本不起作用。
希望有人能给我指出正确的方向,因为我还没有找到任何关于这个案例的具体文件。
问题是 Android.App.Application.Context
并不总是 Activity
上下文。
Xamarin 删除了它并为 Renderers
添加了一个包含上下文的新构造函数。问题出现在这样的情况下,你正在处理不是 CustomRenderer 的东西。
对于这些情况,我使用 James 的插件 CurrentActivityPlugin,它将为您跟踪当前 activity。找到它 here
希望对您有所帮助。-
到目前为止,我一直在尝试使用 IoC 容器从我的 xamarin.forms 应用程序调用对话框警报,但我无法使用此代码在我的应用程序中显示警报:
我的 viewModel 中的代码:
await _dialogService.DisplayMessageAsync("ERROR", "There are errors on your form!", "Cancel", null);
在我的共享项目中,我有这个 DialogService,这是我从 viewModel 调用的服务:
public class DialogService : IDialogService
{
readonly IDialogService _dialogService;
public DialogService()
{
_dialogService = DependencyService.Get<IDialogService>();
}
public void CloseAllDialogs()
{
_dialogService.CloseAllDialogs();
}
public async Task DisplayMessageAsync(string title, string message, string buttonCancelName, Action callback)
{
await _dialogService.DisplayMessageAsync(title, message, buttonCancelName, callback);
}
public async Task DisplayMessageConfirmAsync(string title, string message, string buttonOkName, string buttonCancelName, Action<bool> callback)
{
await _dialogService.DisplayMessageConfirmAsync(title, message, buttonOkName, buttonCancelName, callback);
}
}
所以在我的 Xamarin.Android.XXXXX 我有我的 DialogService 的实现,它是从我的 DialogService 在我的共享项目中调用的,这是代码:
public class DialogService : IDialogService
{
List<AlertDialog> _openDialogs = new List<AlertDialog>();
public void CloseAllDialogs()
{
foreach (var dialog in _openDialogs)
{
dialog.Dismiss();
}
_openDialogs.Clear();
}
public async Task DisplayMessageAsync(string title, string message, string okButton, Action callback)
{
await Task.Run(() => Alert(title, message, okButton, callback));
}
public async Task DisplayMessageConfirmAsync(string title, string message, string okButton, string cancelButton, Action<bool> callback)
{
await Task.Run(() => AlertConfirm(title, message, okButton, cancelButton, callback));
}
bool Alert(string title, string content, string okButton, Action callback)
{
var activity = (Activity)Forms.Context;
//var activity = (Activity)Android.App.Application.Context;
var alert = new AlertDialog.Builder(Android.App.Application.Context);
//var alert = new AlertDialog.Builder(activity);
alert.SetTitle(title);
alert.SetMessage(content);
alert.SetNegativeButton(okButton, (sender, e) =>
{
if (!Equals(callback, null))
{
callback();
}
_openDialogs.Remove((AlertDialog)sender);
});
Device.BeginInvokeOnMainThread(() =>
{
AlertDialog dialog = alert.Show();
_openDialogs.Add(dialog);
dialog.SetCanceledOnTouchOutside(false);
dialog.SetCancelable(false);
});
return true;
}
bool AlertConfirm(string title, string content, string okButton, string cancelButton, Action<bool> callback)
{
var alert = new AlertDialog.Builder(Android.App.Application.Context);
alert.SetTitle(title);
alert.SetMessage(content);
alert.SetNegativeButton(cancelButton, (sender, e) =>
{
callback(false);
_openDialogs.Remove((AlertDialog)sender);
});
alert.SetPositiveButton(okButton, (sender, e) =>
{
callback(true);
_openDialogs.Remove((AlertDialog)sender);
});
Device.BeginInvokeOnMainThread(() =>
{
var dialog = alert.Show();
_openDialogs.Add(dialog);
dialog.SetCanceledOnTouchOutside(false);
dialog.SetCancelable(false);
});
return true;
}
}
因此,每当调用私有方法警报时,它都会抛出如下异常:
Unhandled Exception:
Android.Views.WindowManagerBadTokenException: Unable to add window -- token null is not valid; is your activity running?
如果我切换这行代码就可以更正:
var alert = new AlertDialog.Builder(Android.App.Application.Context);
对于这行代码:
var activity = (Activity)Forms.Context;
var alert = new AlertDialog.Builder(activity);
使用这个的问题我收到这样的 Xamarin.Forms 警告:
'Forms.Context' is obsolete: 'Context is obsolete as of version 2.5. Please use a local context instead.'
而且我有点偏执,我不喜欢收到警告并尝试尽可能更新我的代码,所以,有人可以帮助我使这段代码工作而无需使用过时的代码。因为我找到了将 (Activity)Forms.Context 替换为 Android.App.Application.Context 的答案,但在这种情况下它根本不起作用。
希望有人能给我指出正确的方向,因为我还没有找到任何关于这个案例的具体文件。
问题是 Android.App.Application.Context
并不总是 Activity
上下文。
Xamarin 删除了它并为 Renderers
添加了一个包含上下文的新构造函数。问题出现在这样的情况下,你正在处理不是 CustomRenderer 的东西。
对于这些情况,我使用 James 的插件 CurrentActivityPlugin,它将为您跟踪当前 activity。找到它 here
希望对您有所帮助。-