android-fragments Android getActivity()上下文在PopupWindow中随时间推移而失效

roejwanj  于 2022-11-14  发布在  Android
关注(0)|答案(1)|浏览(139)

我有一个使用popupWindow进行用户聊天的应用程序。它是从Fragment启动的,提供的contextgetActivity()。我将输入popupWindowmultilineEditText,大约5分钟后,我将不断地得到一个崩溃和以下错误:

android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@d1cf1ec is not valid; is your activity running?
    at android.view.ViewRootImpl.setView(ViewRootImpl.java:1147)
    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:471)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)
    at android.widget.PopupWindow.invokePopup(PopupWindow.java:1621)
    at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1375)
    at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1341)
    at android.widget.Editor$PinnedPopupWindow.updatePosition(Editor.java:3817)
    at android.widget.Editor$PinnedPopupWindow.show(Editor.java:3773)
    at android.widget.Editor$SuggestionsPopupWindow.show(Editor.java:4287)
    at android.widget.Editor.replace(Editor.java:587)
    at android.widget.-$$Lambda$DZXn7FbDDFyBvNjI-iG9_hfa7kw.run(Unknown Source:2)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:237)
    at android.app.ActivityThread.main(ActivityThread.java:8167)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

我知道这对解释错误没有太大帮助,但是,就我所知,这是getActivity返回null的问题,而我的popupWindow由于缺少context而强制分离。有什么方法可以避免和/或修复这个问题吗?
下面是一些示例代码,可帮助您可视化popupWindow问题:

if(getActivity() != null) {

        //Retrieve layout inflater
        LayoutInflater layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (layoutInflater != null) {

            //Inflate custom popup layout
            View inflatedView = layoutInflater.inflate(R.layout.popup_chat_layout, null, false);

            writeMessageEditText = inflatedView.findViewById(R.id.writeMessageEditText);

            chatLayoutManager = new LinearLayoutManager(getActivity());
            //Read from bottom-up
            chatLayoutManager.setStackFromEnd(true);
            chatMessagesRecycler.setLayoutManager(chatLayoutManager);

            popupWindow = new PopupWindow(inflatedView, displayWidth, displayHeight, true);

            popupWindow.setAnimationStyle(R.style.PopupAnimation);

            popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
            popupWindow.setHeight(WindowManager.LayoutParams.MATCH_PARENT);

            popupWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);

            //Cap message lines - the purpose is not to cap characters, but ONLY to cap length
            writeMessageEditText.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }

                @Override
                public void afterTextChanged(Editable s) {
                    if (writeMessageEditText.getLayout().getLineCount() > 150) {
                        if (writeMessageEditText.getText() != null) {
                            writeMessageEditText.getText().delete(writeMessageEditText.getText().length() - 1, writeMessageEditText.getText().length());
                        }
                        Toast.makeText(getActivity(), "Message may not exceed 150 lines", Toast.LENGTH_SHORT).show();
                    }
                }
            });

            //This was implemented during testing - possible to remove but fine for now
            dismissChatButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    resetAll();
                    previousChat = null;
                    if(popupWindow != null) {
                        popupWindow.dismiss();
                        popupWindow = null;
                    }
                }
            });

        }

    }
lnvxswe2

lnvxswe21#

尽管我所经历的核心问题的原因是完全错误的,但我想我还是把这个问题留给那些和我一样不擅长阅读堆栈跟踪的人吧。
这可能不是一个完美的解决方案,但是,由于Mike M.的评论,我能够通过禁用xml文件中EditText的建议弹出窗口来解决眼前的问题,如下所示:

android:inputType="textNoSuggestions"

否则,解决方案是将PopupWindow替换为DialogActivity

相关问题