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

希望对您有所帮助。-