BadTokenException: невозможно добавить окно - нулевой токен недействителен После обновления до SDK 29 - PullRequest
0 голосов
/ 09 апреля 2020

После обновления до SDK 29 и AndroidX у меня возникла проблема с созданием нового тоста из FrameLayout. Я все еще получил BadTokenException. Я потратил несколько дней, чтобы попробовать все решения от StackOverflow, но ничего не помогло. Что я пробовал:

  1. Я убедился, что передаю правильный контекст (из фрагмента)
  2. Добавлен android.permission.SYSTEM_ALERT_WINDOW" в манифест. xml
  3. Проверено isFinishing(), поскольку стек взят из onPostExecute

Для SDK 23 все работало нормально. Что изменилось, что для SDK 29 не работает? StackTrace:

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
        at android.view.ViewRootImpl.setView(ViewRootImpl.java:1109)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:432)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)
        at pl.app.myapp.ui.toast.InfoToast.addOverlay(InfoToast.java:102)
        at pl.app.myapp.ui.toast.InfoToast.show(InfoToast.java:195)
        at pl.app.myapp.sections.book.BookFragment.showInfoCreateNewBook(BookFragment.java:141)
        at pl.app.myapp.sections.book.BookFragment.onBooksUpdateSuccess(BookFragment.java:115)
        at pl.app.myapp.sections.book.async.BookUpdaterTask.onSuccess(BookUpdaterTask.java:86)
        at pl.app.myapp.sections.book.async.BookUpdaterTask.onSuccess(BookUpdaterTask.java:23)
        at pl.app.commons.async.base.SimplifiedAsyncTask.sendResult(SimplifiedAsyncTask.java:158)
        at pl.app.commons.async.base.SimplifiedAsyncTask.onPostExecute(SimplifiedAsyncTask.java:145)
        at android.os.AsyncTask.finish(AsyncTask.java:755)
        at android.os.AsyncTask.access$900(AsyncTask.java:192)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:772)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7777)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)

InfoToast:

public void addOverlay(Activity activity) {
    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_TOAST,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

    toastView = createDialogView(activity);
    WindowManager windowManager = (WindowManager) MyApp.getAppContext().getSystemService(Context.WINDOW_SERVICE);
    windowManager.addView(toastView, params);
    viewAnimator.fadeIn();
}

private FrameLayout createDialogView(Context context) {
    FrameLayout dialogView = new FrameLayout(context);
    LayoutInflater inflater = LayoutInflater.from(context);
    View toastRoot = inflater.inflate(R.layout.dialog_info_layout, null);
    toastRoot.setBackgroundColor(context.getResources().getColor(R.color.transparent_black_80_pr));
    toastRoot.setOnClickListener(InfoToast.this);

    TextView tv = (TextView) toastRoot.findViewById(R.id.tv_message);
    tv.setText(message);

    if (iconRes > 0) {
        ImageView imageView = (ImageView) toastRoot.findViewById(R.id.iv_icon);
        imageView.setImageResource(iconRes);
        imageView.setVisibility(View.VISIBLE);
    }

    dialogView.addView(toastRoot);
    viewAnimator = new FadeViewAnimator(toastRoot, R.anim.fade_in_toast_appear, R.anim.fade_out_toast_disappear);
    viewAnimator.setAnimationFinishListener(this);
    return dialogView;
}

public void show(Activity activity) {
    this.activity = activity;
    addOverlay(activity);
    dismissHandler = new DismissHandler();
    dismissHandler.sendMessageDelayed(duration);
}

Фрагмент:

public void onBooksUpdateSuccess(Book book) {
    if (page != null) {
        showInfoAddPageToBook(page, book);
    } else if (isCreatingNew) {
        showInfoCreateNewBook(book);
    }
    getActivity().setResult(Activity.RESULT_OK);
    getActivity().finish();
}
private void showInfoCreateNewBook(Book book) {
    CharSequence dialogMsg = MsgProvider.createbook(book);
    new InfoToast(context)
            .shortDuration()
            .withText(dialogMsg)
            .withIcon(R.drawable.ic_ok)
            .show(this.getActivity());
}
...