Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LayoutAnimation crashes on Android #25832

Closed
gdoudeng opened this issue Jul 26, 2019 · 12 comments
Closed

LayoutAnimation crashes on Android #25832

gdoudeng opened this issue Jul 26, 2019 · 12 comments
Labels
API: LayoutAnimation Bug Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@gdoudeng
Copy link

React Native version:0.60.4
phone:OPPO PAAM00 android 9.0
System:
OS: Windows 10
CPU: (4) x64 Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
Memory: 7.47 GB / 19.89 GB
Binaries:
Node: 10.14.1 - C:\Program Files\nodejs\node.EXE
Yarn: 1.13.0 - ~\AppData\Roaming\npm\yarn.CMD
npm: 6.9.0 - ~\AppData\Roaming\npm\npm.CMD
Watchman: 4.9.4 - G:\Users\ASUS\watchman\watchman.EXE
SDKs:
Android SDK:
Android NDK: 19.0.5232133

Steps To Reproduce

1.UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
2.LayoutAnimation.spring();
3.this.setState to Update view

Describe what you expected to happen:
Render layout animation

Not all layout animations are abnormal. Only some layout animations are abnormal. Sometimes some views disappear after executing the layout animation, and then the program crashes when executed again.But normal in version 0.59.10.

Snack, code example, screenshot, or link to a repository:

adb logcat show this

2019-07-26 14:02:00.744 26524-26524/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.reactproject, PID: 26524
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewParent android.view.View.getParent()' on a null object reference
        at com.facebook.react.uimanager.layoutanimation.LayoutAnimationController.shouldAnimateLayout(LayoutAnimationController.java:89)
        at com.facebook.react.uimanager.NativeViewHierarchyManager.manageChildren(NativeViewHierarchyManager.java:445)
        at com.facebook.react.uimanager.UIViewOperationQueue$ManageChildrenOperation.execute(UIViewOperationQueue.java:228)
        at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:844)
        at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:952)
        at com.facebook.react.uimanager.UIViewOperationQueue.access$2200(UIViewOperationQueue.java:44)
        at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:1012)
        at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
        at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:172)
        at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:84)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1022)
        at android.view.Choreographer.doCallbacks(Choreographer.java:836)
        at android.view.Choreographer.doFrame(Choreographer.java:760)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1010)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:232)
        at android.app.ActivityThread.main(ActivityThread.java:7154)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:576)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:878)
2019-07-26 14:02:00.885 8889-8889/? E/PhoneState: iconId is 0android.widget.ImageView{65ff7d0 G.ED..... ......I. 0,0-13,36 #7f0a0116 app:id/data_inout}
2019-07-26 14:02:00.886 8889-8889/? E/PhoneState: iconId is 0android.widget.ImageView{f3e13c9 G.ED..... ......I. 0,0-0,0 #7f0a0116 app:id/data_inout}
2019-07-26 14:02:00.927 768-768/? E/lowmemorykiller: Error writing /proc/26524/oom_score_adj; errno=22
2019-07-26 14:02:01.062 2044-2489/? E/InputDispatcher: channel 'ab4bf97 com.reactproject/com.reactproject.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
2019-07-26 14:02:01.365 2044-27130/? E/Environment: Path requests must specify a user by using UserEnvironment
    java.lang.Throwable
        at android.os.Environment.throwIfUserRequired(Environment.java:1076)
        at android.os.Environment.getExternalStorageDirectory(Environment.java:516)
        at com.android.server.am.ColorEapUtils.isLowStorage(ColorEapUtils.java:951)
        at com.android.server.am.ColorEapUtils.collectFile(ColorEapUtils.java:533)
        at com.android.server.DropBoxManagerService.add(DropBoxManagerService.java:404)
        at com.android.server.DropBoxManagerService$2.add(DropBoxManagerService.java:175)
        at android.os.DropBoxManager.addText(DropBoxManager.java:283)
        at com.android.server.am.ActivityManagerService$27.run(ActivityManagerService.java:18440)
2019-07-26 14:02:01.985 7457-11733/? E/SceneService.AdUploadResponseData: parseJson, ret = 1008, data = null; errorMsg = KX85ODP-1564120921457#nearbyInfoResponse is null

0.60.4 show this
The bottom cell disappeared.Then the program crashes
Aaron Swartz

0.59.10 is normal
Aaron Swartz

@gdoudeng gdoudeng added the Bug label Jul 26, 2019
@gdoudeng gdoudeng changed the title LayoutAnimation.spring() crashes on Android LayoutAnimation crashes on Android Jul 27, 2019
@msinghus96
Copy link

For hotfix just wrap your component inside parent view(If your are using conditional rendering make sure wrap that view outside that condition. This will fix that issue..

@jomla97
Copy link

jomla97 commented Nov 6, 2019

My project is suffering from this at the moment. The solution by @msinghus96 isn't working for me unfortunately.

For hotfix just wrap your component inside parent view(If your are using conditional rendering make sure wrap that view outside that condition. This will fix that issue..

Any other ideas?

@msinghus96
Copy link

My project is suffering from this at the moment. The solution by @msinghus96 isn't working for me unfortunately.

For hotfix just wrap your component inside parent view(If your are using conditional rendering make sure wrap that view outside that condition. This will fix that issue..

Any other ideas?

Can you share your code.

@jomla97
Copy link

jomla97 commented Nov 8, 2019

@msinghus96 Here's the component using the experimental LayoutAnimation:

import Text from './Text.js';
import SectionButton from './ExpandableCard/SectionButton.js';
import SectionListRowButton from './ExpandableCard/SectionListRowButton.js';

type Props = {};
export default class ExpandableCard extends Component<Props>{
  constructor(props) {
    super(props);

    this.state = {
      expanded: false
    };

    if(Platform.OS === "android"){
      if(UIManager.setLayoutAnimationEnabledExperimental){
        UIManager.setLayoutAnimationEnabledExperimental(true);
      }
    }
  }

  componentDidUpdate(prevProps, prevState){
    if(this.props.expandable === false && this.state.expanded){
      LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
      this.setState({expanded: false});
    }
  }

  toggleExpanded(){
    if(this.props.expandable !== false){
      LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
      this.setState({expanded: !this.state.expanded});
    }
  }

  render(){
    return (
      <TouchableWithoutFeedback onPress={() => this.toggleExpanded()}>
        <View style={Styles.ExpandableCard.wrapper}>
          {
            !this.state.expanded ?
            <View style={Styles.ExpandableCard.retractedView}>
              <Text style={Styles.ExpandableCard.retractedViewTitle}>{this.props.retractedTitle}</Text>
              <View style={Styles.ExpandableCard.retractedViewIconsWrapper}>
                {
                  this.props.retractedIcons !== undefined && this.props.retractedIcons.length > 0 ?
                  this.props.retractedIcons.map((icon, key) => {
                    var IconLibrary = icon.library;

                    return (
                      <IconLibrary key={key} name={icon.name} style={Styles.ExpandableCard.retractedViewIcon}/>
                    );
                  })
                  : null
                }
              </View>
            </View>
            :
            <View style={{height: this.state.expanded ? null : 0}}>
              {
                this.props.sections.map((section, sectionKey) => (
                  <View key={sectionKey} style={Styles.ExpandableCard.expandedViewSection}>
                    <View style={Styles.ExpandableCard.expandedViewSectionTitleWrapper}>
                      <Text style={Styles.ExpandableCard.expandedViewSectionTitle}>{section.title}</Text>
                      <View style={Styles.ExpandableCard.expandedViewSectionButtonWrapper}>
                        {
                          section.buttons !== undefined && section.buttons !== null ?
                          section.buttons.map((button, key) => (<SectionButton key={key} {...button}/>))
                          : null
                        }
                      </View>
                    </View>
                    <View style={Styles.ExpandableCard.expandedViewSectionList}>
                      {
                        section.list.map((sectionListRow, sectionListKey) => (
                          <View key={sectionListKey} style={Styles.ExpandableCard.expandedViewSectionListRow}>
                            <Text style={Styles.ExpandableCard.expandedViewSectionListRowText}>{sectionListRow.value}</Text>
                            <View style={Styles.ExpandableCard.expandedViewSectionListRowButtonWrapper}>
                              {
                                sectionListRow.buttons !== undefined && sectionListRow.buttons !== null ?
                                sectionListRow.buttons.map((button, key) => (<SectionListRowButton key={key} {...button}/>))
                                : null
                              }
                            </View>
                          </View>
                        ))
                      }
                    </View>
                  </View>
                ))
              }
            </View>
          }
        </View>
      </TouchableWithoutFeedback>
    );
  }
}

It can pretty much be summed up with this:

export default class ExpandableCard extends Component<Props>{
  constructor(props) {
    super(props);

    this.state = {
      expanded: false
    };

    if(Platform.OS === "android"){
      if(UIManager.setLayoutAnimationEnabledExperimental){
        UIManager.setLayoutAnimationEnabledExperimental(true);
      }
    }
  }

  toggleExpanded(){
    if(this.props.expandable !== false){
      LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
      this.setState({expanded: !this.state.expanded});
    }
  }

  render(){
    return (
      <TouchableWithoutFeedback onPress={() => this.toggleExpanded()}>
        <View style={Styles.ExpandableCard.wrapper}>
          {
            !this.state.expanded ?
            <View style={Styles.ExpandableCard.retractedView}>
              
            </View>
            :
            <View style={{height: this.state.expanded ? null : 0}}>

            </View>
          }
        </View>
      </TouchableWithoutFeedback>
    );
  }
}

@jomla97
Copy link

jomla97 commented Nov 29, 2019

If anyone needs it I've found a viable alternative:

I've successfully implemented Transitioning from react-native-reanimated, which works much in the same way. A quite important fix was merged into master a couple of days ago though, which version 1.4.0 does not include. I installed it directly from the master github branch.

@gdoudeng gdoudeng closed this as completed Jan 1, 2020
@jomla97
Copy link

jomla97 commented Jan 2, 2020

Hey @gdoudeng why did you close the issue?

@elicwhite
Copy link
Member

If anyone is able to provide a simplified, standalone repro that would be super helpful to investigate this. Ideally the repro should use Expo's Snack. We know there are some crashes with Layout Animations on Android but have had trouble tracking them all down. If you could create a repro for this we'd greatly appreciate it.

@elicwhite elicwhite reopened this Jan 13, 2020
@mjstelly
Copy link

mjstelly commented Jan 25, 2020

Unfortunately, @msinghus96, your solution did not resolve my similar issue. The called method

  const expandItem = () => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
    setExpanded(!expanded)
  }

executed in component property onPress={expandItem}
from here:
this.props.orderHistoryData.map(userData => <UserOrders data={userData} key={userData.id} />)
is already wrapped in a ScrollView which itself is wrapped in a parent View. I continue to receive the same error
unknown:ReactNative: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewParent android.view.View.getParent()' on a null object reference

@TheSavior I'll see if I can replicate this in minimal POC app.
UPDATE: Unfortunately, I am unable to reproduce the error using this expo example. Anyone else have a workaround for this bug?

@k3nda
Copy link

k3nda commented Feb 10, 2020

Yes, same issue here.
Env:

  • Only Android 8 (only real device, not reproduced on emulator)
  • react-native: 0.61.0-rc.3

This code:

if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
  UIManager.setLayoutAnimationEnabledExperimental(true)
}

together with:

  onAccountDetailToggle = () => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.spring)
    this.setState((state) => ({ isSliderVisible: !state.isSliderVisible }))
  }

makes app crash. For first click when panel is expanded it is ok but for the second click when it should hide then app crash.

@elicwhite
Copy link
Member

@k3nada, can you put that into a complete example into an expo snack that crashes. See my comment above.

@stale
Copy link

stale bot commented May 10, 2020

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label May 10, 2020
@stale
Copy link

stale bot commented May 17, 2020

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

@stale stale bot closed this as completed May 17, 2020
@facebook facebook locked as resolved and limited conversation to collaborators May 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
API: LayoutAnimation Bug Platform: Android Android applications. Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests

7 participants