【问题标题】:Xamarin.Forms Calling Dialog from Xamarin.Android Project Throws an Exception来自 Xamarin.Android 项目的 Xamarin.Forms 调用对话框引发异常
【发布时间】:2020-01-08 17:12:12
【问题描述】:

到目前为止,我一直在尝试使用 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;
    }
}

所以每当调用私有方法 alert 时,它都会抛出如下异常:

未处理的异常:

Android.Views.WindowManagerBadTokenException: 无法添加窗口 -- 令牌 null 无效;您的活动正在进行吗?

如果我切换这行代码可以更正:

var alert = new AlertDialog.Builder(Android.App.Application.Context);

对于这行代码:

var activity = (Activity)Forms.Context;
var alert = new AlertDialog.Builder(activity);

使用它的问题我收到这样的 Xamarin.Forms 警告:

'Forms.Context' 已过时:'从 2.5 版开始,上下文已过时。 请改用本地上下文。'

而且我有点强迫症,我不喜欢发出警告并尝试尽可能更新我的代码,所以有人可以帮助我使此代码工作而无需使用过时的代码。因为我找到了仅将 (Activity)Forms.Context 替换为 Android.App.Application.Context 的答案,但在这种情况下它根本不起作用。

希望有人可以为我指明正确的方向,因为我无法找到任何关于此案例的具体文档。

【问题讨论】:

    标签: xamarin xamarin.forms xamarin.android dialog android-alertdialog


    【解决方案1】:

    问题是Android.App.Application.Context 并不总是Activity 上下文。

    Xamarin 删除了这个并为 Renderers 添加了一个新的构造函数,其中包括上下文。问题出现在这样的情况下,您正在处理不是 CustomRenderer 的东西。

    对于这些情况,我使用 James 的插件 CurrentActivityPlugin,它将为您跟踪当前活动。找到它here

    希望这会有所帮助。-

    【讨论】:

      猜你喜欢
      • 2019-01-22
      • 2016-11-22
      • 2011-05-02
      • 1970-01-01
      • 2018-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多