Search code examples
c#androidxamarinmvvmcrossandroid-alertdialog

Dismissing a AlertDialog gives warning Attempted to finish an input event but the input event receiver has already been disposed


I have a view with button, On click of button i am opening up a Alert Dialog. Which i am creating using below code

    List<String> data = new List<string> { "Hello1", "Hello2", "Hello3", "Hello4" };

    void ChangeTubeButton_Click(object sender, EventArgs e)
    {
        AlertDialog.Builder builder;
        builder = new AlertDialog.Builder(Context);
        builder.SetTitle("Select Tube").SetItems(data.ToArray(), RowSelected);
        AlertDialog alert = builder.Create();
        alert.Show();
    }

    void RowSelected(object senderObject, DialogClickEventArgs eventArgs)
    {
        if (eventArgs.Which >= 0 && eventArgs.Which < data.Count)
        {
            String selectedHello = data.ElementAt(eventArgs.Which);
        }
    }

Alert shows up on UI properly and am able to select row properly. its just that when i tap outside on the screen. Alert dismisses but alse gives warning in Logcat.

[InputEventReceiver] Attempted to finish an input event but the input event receiver has already been disposed.
[ViewRootImpl[NavigationView]] Dropping event due to root view being removed: MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=133.8952, y[0]=-190.78308, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=88925144, downTime=88925129, deviceId=1, source=0x1002 }
[InputEventReceiver] Attempted to finish an input event but the input event receiver has already been disposed.

Should i be concerned about this warning? And i want to keep my logs window clean. If anyone can help regarding the warning.


Solution

  • This is not related with your code.

    When you tap outside on the screen, this ACTION_DOWN event queued to app's Message queue. Then it is delivered to your AlerDialog class through ViewPostImeInputStage class and finally ViewPostImeInputStage send this input event to AlerDialog's onTouchEvent listener.

    Since this didn't happened inside your AlertDialog, your AlerDialog will call dismiss() method:

    public boolean onTouchEvent(MotionEvent event) 
    {
        if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) 
        {
             cancel();//This will call dismiss() method.
             return true;
        }
        return false;
    }
    

    Dissmiss() try to close AlertDialog and AlertDialog::onDetachedWindow call WindowInputEventReceiver::dispose() first.

    And then ViewPostImeInputStage call WindowInputEventReceiver::finishInputEvent to finish that ACTION_DOWN event. However WindowInputEventReceiver instance is already disposed so it throw warning messages.

    When you create a AlertDialog, it will associated with a WindowManager, ViewRootImpl is bridge between WindowManager and a DecorView(its relationship with your AlertDialog like this : DecorView -> Activity -> your AlertDialog). You could this in AlerDialog source code :

    public AlertDialog create() {  
            final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);  
            P.apply(dialog.mAlert);  
            dialog.setCancelable(P.mCancelable);  
            if (P.mCancelable) {  
                dialog.setCanceledOnTouchOutside(true);  
            }  
            dialog.setOnCancelListener(P.mOnCancelListener);  
            if (P.mOnKeyListener != null) {  
                dialog.setOnKeyListener(P.mOnKeyListener);  
            }  
            return dialog;  
        }      
    
    Dialog(Context context, int theme, boolean createContextWrapper) {  
      mContext = createContextWrapper ? new ContextThemeWrapper(context, theme) : context;  
    
      mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);  
    
      Window w = PolicyManager.makeNewWindow(mContext);  
      mWindow = w;  
      w.setCallback(this);  
      w.setWindowManager(mWindowManager, null, null);  
      w.setGravity(Gravity.CENTER);  
      mUiThread = Thread.currentThread();  
      mListenersHandler = new ListenersHandler(this);  
    }  
    

    The following motion event "ACTION_MOVE" can't be delievered to AlertDialog since it has been disposed, so the ViewRootImpl will Dropping ACTION_MOVE event and throw warning messages.