После обновления до SDK 29 и AndroidX у меня возникла проблема с созданием нового тоста из FrameLayout. Я все еще получил BadTokenException. Я потратил несколько дней, чтобы попробовать все решения от StackOverflow, но ничего не помогло. Что я пробовал:
- Я убедился, что передаю правильный контекст (из фрагмента)
- Добавлен
android.permission.SYSTEM_ALERT_WINDOW"
в манифест. xml - Проверено
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());
}