Android app crash in play store prelaunch report but working in real device

前端 未结 3 1663
执念已碎
执念已碎 2021-02-05 15:04

Not able to track crash in the project, I got this error in play store pre-launch section, it showing on click of EditText, it got the error. but not getting any cr

3条回答
  •  别跟我提以往
    2021-02-05 15:43

    I was seeing his same error, both in the pre-launch report and in FireBase test lab. I spent several hours looking into this and I am sure it is a bug that only affects SDK <= 23 and is triggered by AccessibilityNodeInfo#performAction(ACTION_SET_TEXT). It seems this method completely ignores the maxLength attribute which in turn causes the IndexOutOfBoundsException.

    You can duplicate this same exception with the following code, making sure the string "1234" is longer than your maxLength:

     Bundle arguments = new Bundle();
     arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "1234");
     mEditText.performAccessibilityAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
    

    So, what to do about it?

    One option is to just ignore it as it is likely to affect a very small subset of users. that is unless you think you might have many users using accessibility functions to enter text and they are also using older SDKs (<= 23).

    Another option would be to set your minSDKVersion in your build.gradle to 24. This might hurt if you have a lot of users using SDK <= 23

    A third option would be to use this very ugly workaround I came up with:

    if(Build.VERSION.SDK_INT <= 23){
            ViewGroup rootView = findViewById(R.id.your_layout_that_contains_edittexts);
            ArrayList views = rootView.getTouchables();
            for(View view : views){
                if(view instanceof EditText){
                    EditText mEditText = (EditText)view;
                    mEditText.setAccessibilityDelegate(new View.AccessibilityDelegate() {
                        @Override
                        public boolean performAccessibilityAction(View host, int action, Bundle arguments) {
    
                            if (action == AccessibilityNodeInfo.ACTION_SET_TEXT) {
                                //do something here to make sure index out of bounds does not occur
                                int maxLength = 0;
                                for(InputFilter filter : mEditText.getFilters()){
                                    if(filter instanceof InputFilter.LengthFilter)  {
                                        maxLength = ((InputFilter.LengthFilter)filter).getMax();
                                    }
                                }
    
                                Set keys  = arguments.keySet();
                                for(String key : keys){
                                    if(arguments.get(key) instanceof  CharSequence){
                                        if(arguments.get(key) != null) {
                                            arguments.putCharSequence(key, ((CharSequence) arguments.get(key)).subSequence(0, maxLength));
                                            mEditText.setText(arguments.getCharSequence(key));
                                        }
                                    }
                                }
                            }
                            return true;
                        }
                    });
    
                }
            }
    
        }
    

    OK, so I did say it was ugly, but it does work. Replace your_layout_that_contains_edittexts with the id of a layout that contains all your EditTexts.

    Basically, if SDK <= 23, it cycles through all the EditTexts in the ViewGroup and for each one, overrides the performAccessibilityAction via AccessibilityDelegate and ensures that the text being entered never exceeds the EditText's maxLength value.

提交回复
热议问题