Useful or not, from you.
react-native NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'

Is this a bug report?

yes

Have you read the Contributing Guidelines?

yes, I am sorry that I cant offer more information about this exception except for this stack trace because the crash report was collected from google analytics, I have no idea to reappear this exception.

Environment

Environment: OS: macOS Sierra 10.12.6 Node: 8.4.0 Yarn: 0.27.5 npm: 5.4.0 Android Studio: 3.0

Packages: (wanted => installed) react-native: 0.51.0 => 0.51.0 react: 16.0.0-alpha.12 => 16.0.0-alpha.12

Target Platform: Android (7.1.1) mobile:MIX 2 android:7.1.1 java.lang.NullPointerException:
tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)' on a null object reference at android.graphics.drawable.DrawableContainer$DrawableContainerState.getChild(DrawableContainer.java:888) at android.graphics.drawable.DrawableContainer.selectDrawable(DrawableContainer.java:466) at android.graphics.drawable.StateListDrawable.onStateChange(StateListDrawable.java:104) at android.graphics.drawable.Drawable.setState(Drawable.java:735) at android.graphics.drawable.DrawableWrapper.onStateChange(DrawableWrapper.java:331) at android.graphics.drawable.Drawable.setState(Drawable.java:735) at android.graphics.drawable.LayerDrawable.onStateChange(LayerDrawable.java:1488) at android.graphics.drawable.Drawable.setState(Drawable.java:735) at android.view.View.drawableStateChanged(View.java:18002) at android.widget.TextView.drawableStateChanged(TextView.java:4097) at android.view.View.refreshDrawableState(View.java:18071) at android.view.View.setPressed(View.java:8543) at android.view.View.setPressed(View.java:8521) at android.view.View.onTouchEvent(View.java:11218) at android.widget.TextView.onTouchEvent(TextView.java:8467) at com.facebook.react.views.textinput.ReactEditText.onTouchEvent(ReactEditText.java:150)

That's a useful answer
Without any help

This issue has been causing our app to crash in production as well. It's a nasty bug, because it is really difficult to reproduce. We've found a promising fix for our app, and I'd like to share our findings here to hopefully save others some time & frustration.

Specs and Versions

This bug has caused our app to crash on Samsung, Google, and LG Android devices. We've had crash reports from the following Android versions:

  • 8.0.0
  • 8.1.0
  • 7.1.1

Our app is running:

  • react-native: 0.53.0
  • react: 16.2.0

What causes the crash

Like others have noted in this thread, the issue seems to be triggered by rendering some combination of TextInput, FlatList, and ScrollView components. In our case, we have a screen containing a single TextInput rendered above a FlatList. When one of the items in the FlatList is tapped, the app navigates to a new screen containing a form. This form's root component is a ScrollView that contains a number of TextInput components (along with some buttons and other custom components). Our app crashes when the user taps one of these FlatList items (note that it doesn't happen every time).

Reproducing this issue is difficult. In fact, we've been unable to do so. But we know that the crash occurs at this point in the workflow by watching our Appsee session recordings.

Because we can't reproduce the issue, we've had to rely on the crash logs from Appsee to debug it. I've copied the stack trace from the crash reports below (and omitted some noisy sections). It's more or less identical to the stack traces posted in this thread by others:

0 	java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)' on a null object reference
1 	at android.graphics.drawable.DrawableContainer$DrawableContainerState.createAllFutures(DrawableContainer.java:875)
2 	at android.graphics.drawable.DrawableContainer$DrawableContainerState.getOpacity(DrawableContainer.java:1158)
3 	at android.graphics.drawable.DrawableContainer.getOpacity(DrawableContainer.java:433)
4 	at android.graphics.drawable.InsetDrawable.getOpacity(InsetDrawable.java:258)
5 	at android.view.View.computeOpaqueFlags(View.java:16900)
6 	at android.view.View.setBackgroundDrawable(View.java:21824)
7 	at android.view.View.setBackground(View.java:21717)
8 	at android.view.View.<init>(View.java:5577)
9 	at android.widget.TextView.<init>(TextView.java:1144)
...
13 	at android.widget.EditText.<init>(EditText.java:96)
14 	at com.facebook.react.views.textinput.ReactEditText.<init>(ReactEditText.java:91)
15 	at com.facebook.react.views.textinput.ReactTextInputManager.createViewInstance(ReactTextInputManager.java:91)
16 	at com.facebook.react.views.textinput.ReactTextInputManager.createViewInstance(ReactTextInputManager.java:61)
...
35 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

Source of the problem

After reading through this thread and doing a few hours or research, I found the underlineColorAndroid prop handler in the ReactTextInputManager.java file:

@ReactProp(name = "underlineColorAndroid", customType = "Color")
public void setUnderlineColor(ReactEditText view, @Nullable Integer underlineColor) {
  // Drawable.mutate() can sometimes crash due to an AOSP bug:
  // See https://code.google.com/p/android/issues/detail?id=191754 for more info
  Drawable background = view.getBackground();
  Drawable drawableToMutate = background.getConstantState() != null ?
    background.mutate() :
    background;

  if (underlineColor == null) {
    drawableToMutate.clearColorFilter();
  } else {
    drawableToMutate.setColorFilter(underlineColor, PorterDuff.Mode.SRC_IN);
  }
}

The bug report linked to in the comment contains the following stack trace:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable()' on a null object reference
    at android.graphics.drawable.LayerDrawable$ChildDrawable.<init>(LayerDrawable.java:1723)
    at android.graphics.drawable.LayerDrawable$LayerState.<init>(LayerDrawable.java:1792)
    at android.graphics.drawable.LayerDrawable.createConstantState(LayerDrawable.java:152)
    at android.graphics.drawable.LayerDrawable.mutate(LayerDrawable.java:1652)

This matches the stack trace we we are encountering in our app. I don't pretend to fully understand the underlying problem, but it seems likely that the cause of our app crashing in production is due to the Drawable.mutate() bug being triggered. This happens when we try to set the underlineColorAndroid prop on our TextInput component (and thus invoke the ReactTextInputManager.setUnderlineColor method).

Our app was rendering a TextInput with the following props, one of which was underlineColorAndroid="transparent":

<TextInput
  ref={this.handleRef}
  value={this.props.value}
  autoCorrect={false}
  autoCapitalize="none"
  underlineColorAndroid="transparent"
  onSubmitEditing={this.handleSubmit}
  onChangeText={this.props.onChangeText}
  onFocus={this.handleFocused}
  onBlur={this.handleBlur}
  clearButtonMode="always"
/>

How we fixed it

We needed to set this prop in order to remove the underline from the TextInput components in our app. But based on our findings, its prop handler appeared to be triggering an Android bug that caused the app to crash occasionally.

Fortunately, there is another way to remove underlines from TextInput components on Android. You can add a line to the android/app/src/main/res/values/styles.xml file:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowExitAnimation">@android:anim/fade_out</item>
        <item name="android:windowBackground">@drawable/splash_screen</item>
+       <item name="android:editTextBackground">@android:color/transparent</item>
    </style>
</resources>

Note that I've also seen the following suggested, but this did not remove the underlines for us:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowExitAnimation">@android:anim/fade_out</item>
        <item name="android:windowBackground">@drawable/splash_screen</item>
    </style>

+   <!-- This did *not* work for us... -->
+   <style name="AppEditTextStyle" parent="@style/Widget.AppCompat.EditText">
+     <item name="android:background">@android:color/transparent</item>
+   </style>
</resources>

This does not address the underlying issue. It is just a workaround that involves avoiding usage of the underlineColorAndroid prop on TextInput components.

I cannot yet say with certainty that this actually works, because I've been unable to reproduce the issue locally. We'll be deploying this change in an update to our app in the coming weeks. After that, we'll have to wait awhile to see if it occurs anymore. I'll try to report back with our findings.

Good luck to everybody wrestling with this frustrating issue! I hope this helps.

I know how to reproduce this situation. Click back in the form as you said, and then click item in the flatlist to enter the form. Repeat about ten times, and a little faster, this error will occur. You can reproduce the error according to what I said.