My users have been running into the same problem and it appears to be caused by one or more accessibility options being turned on. Some of my users were using the Pebble smart watch which installs an accessibility option - so it's not just TalkBack, etc.
Take a look at this bit of KitKat's View#setFlags()
method at https://github.com/android/platform_frameworks_base/blob/kitkat-mr1-release/core/java/android/view/View.java#L9006
if (accessibilityEnabled) {
...
notifyViewAccessibilityStateChangedIfNeeded(
AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
}
that sends you down the rabbit hole ending in a NullPointerException
if it's executed before the View is attached to the view hierarchy (i.e. is has no parent) because in View#sendAccessibilityEventUncheckedInternal()
at https://github.com/android/platform_frameworks_base/blob/kitkat-mr1-release/core/java/android/view/View.java#L4952 we have:
getParent().requestSendAccessibilityEvent(this, event);
For my app, I am creating a View
subclass programmatically and was calling View#setOnClickListener()
in the constructor. Instead, I now call View#setOnClickListener()
from
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
/* Due to a bug in how Android 4.4 handles accessibility options,
* we can't set the onClick listener until this View has a parent or we will
* get an NPE. */
setOnClickListener(this);
}
It works because this View
will have a parent by the time View#onAttachedToWindow()
gets called.
Your stack trace is more problematic though. You're falling into the rabbit hole via attributes on an XML layout. I haven't come up with an idea for you. One thought is that this must only happen at app startup - otherwise virtually all inflations of XML layouts would trigger the crash because there are so many paths that take you through View#setFlags()
. In my app, this one spot appears to be the only crash and it happens at app startup. It's not a pleasant idea but one possibility is to re-order things to inflate this view later.