Невозможно запустить ProgressDialog - BadTokenException во время показа

У меня проблема с ProgressDialog в MVVMCross. Я получаю Android.Views.WindowManagerBadTokenException: при создании ProgressDialog через IReportService, где у меня есть контекст из setup.cs.

public class Setup
        : MvxBaseAndroidBindingSetup
    {
        public Setup(Context applicationContext)
            : base(applicationContext)
        {
        }

        protected override MvxApplication CreateApp()
        {
            return new NoSplashScreenApp();
        }
        public class Converters
        {
          public readonly MvxVisibilityConverter Visibility = new MvxVisibilityConverter();
        }
        protected override IEnumerable<Type> ValueConverterHolders
      {
          get { return new[] {typeof (Converters)}; }
      }
        protected override void InitializeLastChance()
        {
            var errorHandler = new ReportsDisplayer(ApplicationContext);
            base.InitializeLastChance();
        }

    }
public class ReportsDisplayer
: IMvxServiceConsumer<IReportsSource>
      , IMvxServiceConsumer<IMvxAndroidCurrentTopActivity>
{
    private readonly Context _applicationContext;
    private ProgressDialog _progressDialog;

    public ReportsDisplayer(Context applicationContext)
    {
        _applicationContext = applicationContext;

        var source = this.GetService<IReportsSource>();
        source.ErrorReported += (sender, args) => ShowError(args.Message);
        source.MessageReported += (sender, args) => ShowMessage(args.Title, args.Message);
        source.ProgressDialogShowed += (sender, args) => ShowProgressDialog(args.Title, args.Message);
        source.ProgressDialogDismiss += (sender, args) => DismissProgressDialog();

    }

    private void ShowError(string message)
    {
        var activity = this.GetService<IMvxAndroidCurrentTopActivity>().Activity as IMvxBindingActivity;
        View layoutView = activity.NonBindingInflate(Resource.Layout.ToastLayout_Error, null);

        var text1 = layoutView.FindViewById<TextView>(Resource.Id.ErrorText1);
        text1.Text = "Błąd";
        var text2 = layoutView.FindViewById<TextView>(Resource.Id.ErrorText2);
        text2.Text = message;

        var toast = new Toast(_applicationContext);

        toast.SetGravity(GravityFlags.CenterVertical, 0, 0);
        toast.Duration = ToastLength.Long;
        toast.View = layoutView;
        toast.Show();
    }
    private void ShowMessage(string title, string message)
    {
        var activity = this.GetService<IMvxAndroidCurrentTopActivity>().Activity as IMvxBindingActivity;
        View layoutView = activity.NonBindingInflate(Resource.Layout.ToastLayout_Message, null);
        var text1 = layoutView.FindViewById<TextView>(Resource.Id.MessageText1);
        text1.Text = title;
        var text2 = layoutView.FindViewById<TextView>(Resource.Id.MessageText2);
        text2.Text = message;

        var toast = new Toast(_applicationContext);
        toast.SetGravity(GravityFlags.CenterVertical, 0, 0);
        toast.Duration = ToastLength.Long;
        toast.View = layoutView;
        toast.Show();
    }
    private void ShowProgressDialog(string title, string message)
    {
        _progressDialog = new ProgressDialog(_applicationContext);
        _progressDialog .SetTitle(title);
        _progressDialog .SetMessage(message);
        _progressDialog .Show(); 
    }
    private void DismissProgressDialog()
    {
        _progressDialog .Dismiss();
    }
}

ToastMessages отлично работают с использованием локального контекста, а ProgressDialog — нет. Отладчик аварийно завершает работу при запуске _progressBar.Show(). Я перерыл весь интернет, но решения не нашел. Любые предложения более чем приветствуются!


person lechu    schedule 07.08.2012    source источник


Ответы (1)


Я подозреваю, что проблема такая же, как Android 1.6: android .view.WindowManager$BadTokenException: невозможно добавить окно — нулевой токен не для приложения или Ошибка при попытке открыть диалоговое окно: android.view.WindowManager$BadTokenException

то есть эта строка: Context appContext = this.getApplicationContext(); должен идти, и вместо этого вы используете указатель на действие, в котором вы находитесь (возможно, это).

Я тоже укусил это сегодня, раздражает то, что getApplicationContext() дословно взят с developer.android.com :(

Так что постарайтесь:

private void ShowProgressDialog(string title, string message)
{
     var activity = this.GetService<IMvxAndroidCurrentTopActivity>().Activity;
    _progressDialog = new ProgressDialog(activity);
    _progressDialog .SetTitle(title);
    _progressDialog .SetMessage(message);
    _progressDialog .Show(); 
}
person Stuart    schedule 07.08.2012
comment
Обратите внимание, что IMvxServiceConsumer<T> and GetService<T> were replaced with Mvx.Resolve<T> in v3. - person hlovdal; 17.03.2015