question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

LayoutAnimation crash on Android

See original GitHub issue

We’ve addressed 3 crashes so far that are related to LayoutAnimation while we are using RN 59.8 release in our app and each of them is impacting our users a lot.:

  1. com.facebook.react.uimanager.IllegalViewOperationException: Trying to remove a view index above child count 0 at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren …

  2. java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child’s parent first. … at android.view.ViewGroup.addView at com.facebook.react.uimanager.ViewGroupManager.addView at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren …

  3. java.lang.IndexOutOfBoundsException: index=28 count=27 … at android.view.ViewGroup.addView at com.facebook.react.uimanager.ViewGroupManager.addView at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren …

We’ve also noticed there are a couple of commits trying to fix these crashes after 59.8 release and two of them are eventually merged:

  1. https://github.com/facebook/react-native/commit/20b4879dfd34716997e92bb5d89b0e4f873fef98#diff-55b8191729d605b79bc0964d365ce96f
  2. https://github.com/facebook/react-native/commit/5f027ec64d6764fbbb9813fabb373194dec79db7#diff-55b8191729d605b79bc0964d365ce96f

which are built in the patch that we are going to apply to our app as well. This patch significantly reduces the chance of the first and third crashes happening, but it’s still able to reproduce the second one, ‘java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child’s parent first’.

Since it’s not easy to describe all details here, there is a collated document attached to this ticket that includes everything about the crash, e.g. stack trace, customized log and relevant code snippet.

React Native version:

59.8

Steps To Reproduce

We are using FlatList to wrap a list of cards and applying LayoutAnimation to it when state of content changes. Here is how we setup LayoutAnimation in JS code:

        update: {
            	type: LayoutAnimation.Types.linear,
            	property: LayoutAnimation.Properties.scaleXY,
            	duration: xxx,
        },
        delete: {
            	type: LayoutAnimation.Types.linear,
            	property: LayoutAnimation.Properties.opacity,
            	duration: xxx,
        },

From our scenario, the steps to reproduce are:

  1. Play the FlaList for a while which would trigger LayoutAnimation a couple of times
  2. Leave the current screen and then come back immediately
  3. Crash happens when application is trying to restore the previous state of this screen

Describe what you expected to happen: Everything should be fine, no crash happens at least.

Snack, code example, screenshot, or link to a repository: Here are some critical logs when the crash happens:

 Optimizer, addNonLayoutNode, parent = 4905, child = 4493, index = 0
 Optimizer, addNonLayoutNode, parent = 4905, child = 4493, index = 0
 Optimizer, addNonLayoutNode, parent = 4905, child = 4539, index = 1
 Optimizer, addNonLayoutNode, parent = 4905, child = 4539, index = 1
 Optimizer, addNonLayoutNode, parent = 4905, child = 4587, index = 2
 Optimizer, addNonLayoutNode, parent = 4905, child = 4587, index = 2
 Optimizer, addNonLayoutNode, parent = 4905, child = 4635, index = 3
 Optimizer, addNonLayoutNode, parent = 4905, child = 4635, index = 3
 Optimizer, addNonLayoutNode, parent = 4905, child = 4683, index = 4
 Optimizer, addNonLayoutNode, parent = 4905, child = 4683, index = 4
 Optimizer, addNonLayoutNode, parent = 4905, child = 4729, index = 5
 Optimizer, addNonLayoutNode, parent = 4905, child = 4729, index = 5
 Optimizer, addNonLayoutNode, parent = 4905, child = 4777, index = 6
 Optimizer, addNonLayoutNode, parent = 4905, child = 4777, index = 6
 Optimizer, addNonLayoutNode, parent = 4905, child = 4825, index = 7
 Optimizer, addNonLayoutNode, parent = 4905, child = 4825, index = 7
 Optimizer, addNonLayoutNode, parent = 4905, child = 4863, index = 8
 Optimizer, addNonLayoutNode, parent = 4905, child = 4863, index = 8
 Optimizer, addNonLayoutNode, parent = 4905, child = 4899, index = 9
 Optimizer, addNonLayoutNode, parent = 4905, child = 4899, index = 9

------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [], atIndices: [], removeFrom: [5], tag = 4905
 going to add view, tag = 4785, at 0
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4729, delete = true
 going to add view, tag = 4787, at 0
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4729, delete = true
 going to add view, tag = 4793, at 1
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4729, delete = true
 going to add view, tag = 4779, at 0
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [], atIndices: [], removeFrom: [5], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4777, delete = true
 going to add view, tag = 4783, at 1
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4777, delete = true
 going to add view, tag = 4795, at 2
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4777, delete = true
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [], atIndices: [], removeFrom: [5], tag = 4905
 going to add view, tag = 4803, at 0
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4825, delete = true
 going to add view, tag = 4807, at 1
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4825, delete = true
 going to add view, tag = 4813, at 2
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4825, delete = true
 going to add view, tag = 4817, at 0
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [], atIndices: [], removeFrom: [5], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4863, delete = true
 going to add view, tag = 4827, at 0
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4863, delete = true
 going to add view, tag = 4829, at 1
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4863, delete = true
 going to add view, tag = 4839, at 0
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [], atIndices: [], removeFrom: [5], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4899, delete = true
 going to add view, tag = 4845, at 1
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4899, delete = true
 going to add view, tag = 4849, at 2
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4899, delete = true

------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [1], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4493, delete = false
 going to add view, tag = 4867, at 1
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4493, delete = false
 going to add view, tag = 4877, at 0
 Optimizer, addNonLayoutNode, parent = 4905, child = 4493, index = 1
 going to add view, tag = 4883, at 1
 Optimizer, addNonLayoutNode, parent = 4905, child = 4493, index = 1

------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5029], atIndices: [3], removeFrom: [], tag = 4905
 going to add view, tag = 4729, at 5
 Optimizer, addNonLayoutNode, parent = 4905, child = 5029, index = 3
 going to add view, tag = 4777, at 6
 Optimizer, addNonLayoutNode, parent = 4905, child = 5029, index = 3

------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5069], atIndices: [5], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5069, index = 5
 Optimizer, addNonLayoutNode, parent = 4905, child = 5069, index = 5

------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5109], atIndices: [7], removeFrom: [], tag = 4905
 going to add view, tag = 4949, at 1
 Optimizer, addNonLayoutNode, parent = 4905, child = 5109, index = 7
 going to add view, tag = 4957, at 0
 Optimizer, addNonLayoutNode, parent = 4905, child = 5109, index = 7
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5147], atIndices: [8], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5147, index = 8
 remove view at 0, normalized index = 0, tag = 4425, parent tag = 4427
 going to add view, tag = 4927, at 0
 Optimizer, addNonLayoutNode, parent = 4905, child = 5147, index = 8
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5185], atIndices: [9], removeFrom: [], tag = 4905
 going to add view, tag = 4959, at 1
 Optimizer, addNonLayoutNode, parent = 4905, child = 5185, index = 9
 Optimizer, addNonLayoutNode, parent = 4905, child = 5185, index = 9
 remove view at 0, normalized index = 0, tag = 4493, parent tag = 4905
 going to add view, tag = 4493, at 1

------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5247], atIndices: [10], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5247, index = 10
 Optimizer, addNonLayoutNode, parent = 4905, child = 5247, index = 10
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5285], atIndices: [11], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5285, index = 11
 Optimizer, addNonLayoutNode, parent = 4905, child = 5285, index = 11
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5323], atIndices: [12], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5323, index = 12
 Optimizer, addNonLayoutNode, parent = 4905, child = 5323, index = 12
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5359], atIndices: [13], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5359, index = 13
 Optimizer, addNonLayoutNode, parent = 4905, child = 5359, index = 13
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5397], atIndices: [14], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5397, index = 14
 Optimizer, addNonLayoutNode, parent = 4905, child = 5397, index = 14
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5435], atIndices: [15], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5435, index = 15
 Optimizer, addNonLayoutNode, parent = 4905, child = 5435, index = 15
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5473], atIndices: [16], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5473, index = 16
 Optimizer, addNonLayoutNode, parent = 4905, child = 5473, index = 16
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5509], atIndices: [17], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5509, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5509, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5547], atIndices: [18], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5547, index = 18
 Optimizer, addNonLayoutNode, parent = 4905, child = 5547, index = 18
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5585], atIndices: [19], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5585, index = 19
 Optimizer, addNonLayoutNode, parent = 4905, child = 5585, index = 19

------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [], atIndices: [], removeFrom: [20], tag = 4905
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5623], atIndices: [20], removeFrom: [], tag = 4905
 remove view at 0, normalized index = 0, tag = 5113, parent tag = 5125
 Optimizer, addNonLayoutNode, parent = 4905, child = 5623, index = 20
 Optimizer, addNonLayoutNode, parent = 4905, child = 5623, index = 20
 remove view at 0, normalized index = 0, tag = 5149, parent tag = 5163
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5659], atIndices: [21], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5659, index = 21
 Optimizer, addNonLayoutNode, parent = 4905, child = 5659, index = 21
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5697], atIndices: [22], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5697, index = 22
 Optimizer, addNonLayoutNode, parent = 4905, child = 5697, index = 22
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5735], atIndices: [23], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5735, index = 23
 Optimizer, addNonLayoutNode, parent = 4905, child = 5735, index = 23
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [], moveTo: [], addTags: [5769], atIndices: [24], removeFrom: [], tag = 4905
 Optimizer, addNonLayoutNode, parent = 4905, child = 5769, index = 24
 Optimizer, addNonLayoutNode, parent = 4905, child = 5769, index = 24

------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [1], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4493, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4493, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 4493, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 4493, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4539, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4539, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 4539, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 4539, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4587, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4587, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 4587, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 4587, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5029, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5029, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5029, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5029, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4635, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4635, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 4635, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 4635, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5069, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5069, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5069, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5069, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4683, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 4683, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 4683, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 4683, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5109, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5109, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5109, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5109, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5147, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5147, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5147, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5147, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5185, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5185, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5185, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5185, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5247, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5247, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5247, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5247, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5285, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5285, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5285, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5285, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5323, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5323, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5323, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5323, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5359, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5359, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5359, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5359, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5397, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5397, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5397, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5397, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5435, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5435, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5435, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5435, index = 17
------------------ (UIManager.manageChildren) tag: 4905, moveFrom: [0], moveTo: [17], addTags: [], atIndices: [], removeFrom: [], tag = 4905
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5473, delete = false
 Optimizer, removeNodeFromParent, parent = 4905, tag = 5473, delete = false
 Optimizer, addNonLayoutNode, parent = 4905, child = 5473, index = 17
 Optimizer, addNonLayoutNode, parent = 4905, child = 5473, index = 17

 remove view at 1, normalized index = 1, tag = 4493, parent tag = 4905
 going to add view, tag = 4493, at 17
 remove view at 0, normalized index = 0, tag = 4539, parent tag = 4905
 going to add view, tag = 4539, at 17
 remove view at 0, normalized index = 0, tag = 4587, parent tag = 4905
 going to add view, tag = 4587, at 17
 remove view at 0, normalized index = 0, tag = 5029, parent tag = 4905
 going to add view, tag = 5029, at 17
 remove view at 0, normalized index = 0, tag = 4635, parent tag = 4905
 going to add view, tag = 4635, at 17
 remove view at 0, normalized index = 0, tag = 4683, parent tag = 4905
 going to add view, tag = 5069, at 17

These logs reflect the whole flow of the crash happening. To help understanding, view 4905 is the view container of the list which is ReactHorizontalScrollContainerView on Android, and crash happens at the last line when adds view 5069, which already has a parent, into view 4905 at index 17.

The code run into this situation due to inconsistent view hierarchy state between ReactShadowNode and NativeViewHierarchyManager when there are pending deletion animations.

In UIImplementation, views will be added into the latest view hierarchy without any pending state calculation, but it does consider the pending state if the index of the view to be added is equal to or larger than the starting position of deleting items in NativeViewHierarchyManager.

Relevant code snippet in UIImplementation.manageChildren():

if (numToMove > 0) {
    Assertions.assertNotNull(moveFrom);
    Assertions.assertNotNull(moveTo);

    for(lastIndexRemoved = 0; lastIndexRemoved < numToMove; ++lastIndexRemoved) {
        i = moveFrom.getInt(lastIndexRemoved);
        indexToRemove = cssNodeToManage.getChildAt(i).getReactTag();
        viewsToAdd[lastIndexRemoved] = new ViewAtIndex(indexToRemove, moveTo.getInt(lastIndexRemoved));
        indicesToRemove[lastIndexRemoved] = i;
        tagsToRemove[lastIndexRemoved] = indexToRemove;
    }
}

if (numToAdd > 0) {
    Assertions.assertNotNull(addChildTags);
    Assertions.assertNotNull(addAtIndices);

    for(lastIndexRemoved = 0; lastIndexRemoved < numToAdd; ++lastIndexRemoved) {
        i = addChildTags.getInt(lastIndexRemoved);
        indexToRemove = addAtIndices.getInt(lastIndexRemoved);
        viewsToAdd[numToMove + lastIndexRemoved] = new ViewAtIndex(i, indexToRemove);
    }
}
for(i = 0; i < viewsToAdd.length; ++i) {
    ViewAtIndex viewAtIndex = viewsToAdd[i];
    ReactShadowNode cssNodeToAdd = this.mShadowNodeRegistry.getNode(viewAtIndex.mTag);
    if (cssNodeToAdd == null) {
        throw new IllegalViewOperationException("Trying to add unknown view tag: " + viewAtIndex.mTag);
    }

    cssNodeToManage.addChildAt(cssNodeToAdd, viewAtIndex.mIndex);
}

And code snippet in NativeViewHierarchyManager.manageChildren():

if (viewsToAdd != null) {
    for(i = 0; i < viewsToAdd.length; ++i) {
        ViewAtIndex viewAtIndex = viewsToAdd[i];
        View viewToAdd = (View)this.mTagsToViews.get(viewAtIndex.mTag);
        if (viewToAdd == null) {
            throw new IllegalViewOperationException("Trying to add unknown view tag: " + viewAtIndex.mTag + "\n detail: " + constructManageChildrenErrorMessage(viewToManage, viewManager, indicesToRemove, viewsToAdd, tagsToDelete));
        }

        int normalizedIndexToAdd = this.normalizeIndex(viewAtIndex.mIndex, pendingIndicesToDelete);
        viewManager.addView(viewToManage, viewToAdd, normalizedIndexToAdd);
    }
}

To help understanding, there is a picture shows the crash flow in the attached doc.

Issue of applying the patch to fix LayoutAnimation on Android.pdf

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:15
  • Comments:33 (6 by maintainers)

github_iconTop GitHub Comments

8reactions
ydongzhucommented, Jun 22, 2020

Looks like no one is working on this? Meanwhile, is there any good substitute to create a properly animated flat list?

I guess this issue is not the priority of FB team for now so they just leave it here, I’ve not had any update for months.

5reactions
briefjudofoxcommented, Feb 18, 2021

I don’t think this is adding anything new to the conversation, but we also started seeing this crash when going from RN 0.61 to 0.63. We had to remove UIManager.setLayoutAnimationEnabledExperimental(true); to avoid the crash.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React Native Android crash with LayoutAnimationController ...
I was running into a similar issue and it was revolving around me having a Modal with buttons that fired the LayoutAnimation ....
Read more >
React Native Android crash with LayoutAnimationController ...
[Solved]-React Native Android crash with LayoutAnimationController.shouldAnimateLayout-React Native. Search. score:1. setImmediate(() => LayoutAnimation.
Read more >
Auto animate layout updates - Android Developers
Here's what a default layout animation looks like when adding items to a list: Layout animation. Create the layout.
Read more >
LayoutAnimation - React Native
Note that in order to get this to work on Android you need to set the following flags via UIManager : if (Platform.OS...
Read more >
React Native LayoutAnimation - Level Up Coding
It also does NOT work on Android and will crash your app, so watch out for that. LayoutAnimation.Properties. These properties allow you to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found