react-native: [0.63.1][Android] Dimensions API stops working randomly after a while

Please provide all the information requested. Issues that do not follow this format are likely to stall.

Description

Using Dimensions.get('window') and Dimensions.addEventListener(...) stops working/firing events randomly after a while.

I can’t figure out exactly what triggers the issue, but after the event listener stops firing, calling get will also return incorrect values (e.g., portrait values even if in landscape). Note that the actual UI still works as expected (rotates/adjusts), but the Dimensions API just completely breaks.

After testing for a couple of hours, the bug seems to happen after a WebView is loaded (with https://github.com/react-native-community/react-native-webview). I can’t tell yet whether this was caused by an upgrade in the WebView library or react native itself. I will be linking this issue there as well.

React Native version:

Run react-native info in your terminal and copy the results here.

info Fetching system and libraries information...
System:
    OS: macOS 10.15.4
    CPU: (4) x64 Intel(R) Core(TM) i5-6267U CPU @ 2.90GHz
    Memory: 108.54 MB / 8.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.16.3 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.4 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.9.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.5, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 23, 26, 28, 29
      Build Tools: 28.0.3, 29.0.2
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.0 AI-193.6911.18.40.6626763
    Xcode: 11.5/11E608c - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_121 - /usr/bin/javac
    Python: 2.7.15 - /Library/Frameworks/Python.framework/Versions/2.7/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1 
    react-native: 0.63.1 => 0.63.1 
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Build a simple Android app with unlocked orientation (that is, allow all orientations)
  2. Use Dimensions API: Dimensions.get('window') and Dimensions.addEventListener(...). For example, registering these on the root’s component mount.
  3. Rotate the device a few times and confirm Dimensions is firing the event
  4. Mount a <WebView /> component and rotate a few times
  5. Unmount the <WebView /> component
  6. Rotate the device again. Observe how Dimensions events no longer fire, and Dimensions.get(...) always return the same values (i.e., they do not update when the UI rotates).

Some logcat warnings when the issue triggers:

2020-07-21 11:35:44.549 30678-31115/com.zinspector3.dev W/cr_media: Requires BLUETOOTH permission
2020-07-21 11:35:44.728 30678-31121/com.zinspector3.dev W/VideoCapabilities: Unrecognized profile 2130706433 for video/avc
2020-07-21 11:35:44.728 30678-31121/com.zinspector3.dev W/VideoCapabilities: Unrecognized profile 2130706434 for video/avc
2020-07-21 11:35:44.738 30678-31121/com.zinspector3.dev W/VideoCapabilities: Unrecognized profile 2130706433 for video/avc
2020-07-21 11:35:44.738 30678-31121/com.zinspector3.dev W/VideoCapabilities: Unrecognized profile 2130706434 for video/avc
2020-07-21 11:35:44.829 30678-31121/com.zinspector3.dev W/VideoCapabilities: Unrecognized profile 2130706433 for video/avc
2020-07-21 11:35:44.829 30678-31121/com.zinspector3.dev W/VideoCapabilities: Unrecognized profile 2130706434 for video/avc
2020-07-21 11:35:44.858 30678-31121/com.zinspector3.dev I/VideoCapabilities: Unsupported profile 4 for video/mp4v-es

-- close webview --

2020-07-21 11:41:34.078 31308-31308/com.zinspector3.dev E/chromium: [ERROR:aw_browser_terminator.cc(125)] Renderer process (32010) crash detected (code -1).

Note: react-navigation is also being used.

Expected Results

Dimensions API should not stop updating just because a possibly buggy component (WebView) is messing with the app.

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

Please provide a Snack (https://snack.expo.io/), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem. You may provide a screenshot of the application if you think it is relevant to your bug report. Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 15
  • Comments: 42 (14 by maintainers)

Commits related to this issue

Most upvoted comments

The fix for this is checked into the master branch (thank you @ajpaulingalls and @ejanzer) and will naturally make its way into the first react-native@0.64 release candidates. If you want it to be included in the future react-native@0.63.4 patch release, please upvote the comment linked below.

https://github.com/react-native-community/releases/issues/212#issuecomment-725612630

Still an issue, and RN 0.64 is just around the corner. This issue could really use some attention since migration is impossible until this is resolved and apps will already lag behind with RN updates.

I made some research and I found that the issue is trigger by DisplayMetricsHolder.java which is a singleton and receive an reference to DisplayMetrics (sWindowDisplayMetrics). The problem appears after WebView is loaded and this reference (sWindowDisplayMetrics) is no longer updated (I guess is overwrite somewhere) and remain with old values. Inside DeviceInfoModule.java method “emitUpdateDimensionsEventcheck” check if dimensions are changed before triggering “didUpdateDimensions” and because the sWindowDisplayMetrics is no longer updated inside DisplayMetricsHolder the old dimensions are equal with the new dimensions and event is never triggered.

I hope someone would fix this issue asap!!!

Repro here: https://github.com/cristianoccazinsp/react-native-dims-bug

Although the webview seems needed to trigger the bug, I believe it is something related to either surface handling or event emitters (that the webview use), but technically any component could trigger the bug.

Running the above example: just run it on android and rotate the device a few times, dimensions will stop updating right away.

@fabriziobertoglio1987 I know you have been getting your hands dirty by debugging some very deep react native bugs. Sorry about tagging you here, but do you have any ideas what could be this bug? Seems like extremely serious since it cripples Android apps.

Can confirm! The issue appears very ranromly but frequently. On native screens the orientation changes are detected correctly. But after switching to a webview screen and rotating the device it stops working and the dimensions either stay in portrait or landscape mode. After that no orientation changes are detected anymore. On iOS we haven’t had any problems.

@jmsbrett this is fixed in 64.2. I didn’t realize how RN branching worked when I pushed for this to get cherry-picked into 63. I thought that landing it in the master branch was enough for it to naturally flow back into the 64 release, but I was wrong. This is why the first few 64 releases didn’t include the fix.

https://github.com/facebook/react-native/releases/tag/v0.64.2

Dimension update events are now properly sent following orientation change (a6a4d3365f17332e367c34357a07a73f97d6ec83 by @ajpaulingalls)

Unfortunately I’m still seeing this issue with 0.64.0.

It’s android only, and happens pretty consistently, but only after a WebView has been loaded.

Oddly enough, it doesn’t happen in 0.63.4, so this may be a new bug not addressed by the aforementioned PRs.

can confirm we are having serious issues from this bug, can confirm it only affects Android. it appears to happen once a webview comes into the mix. dimensions is such a core ability it really cripples several areas of any app!

I will try to test a fresh project to discard webviews and navigation causing issues. But it really seems like something internal from RN is breaking in a very bad way and I don’t really see how other libraries could affect it.

I have the issue with Keyboard listener event but I think the same reason with Dimensions. After load web-view or some ads banner then call lockToLandscape method from react-native-orientation-locker, keyboardDidShow event will be triggered but my screen not render TextInput. https://github.com/facebook/react-native/blob/7100756bb8b0b1ac85ccaa32c0ce5c1cc70d524f/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java#L662

I forked react-native from the react-native@0.63.3 tag and then reverted the 3 dimensions commits in reverse order (Jan 22 commit, then Jan 19 commit, then Jan 18 comit) and tested incrementally.

This bug starts to happen after the earliest of those 3 commits went in:

  • Only update dimensions in ReactRootView if they’ve changed (cc3e27d by @ejanzer)

What I’m seeing is that the Dimensions.addEventListener callbacks are firing normally until a web view gets rendered. Once that happens, the callbacks stop firing. This causes all kinds of critical UI bugs on rotation once the dimensions module breaks down like this. I think that Issue #29323 may be another instance of the same issue.

@ejanzer @JoshuaGross @mdvacca is there a way to patch this without losing the functionality this commit adds in a way that works for everyone?

There’s yet another issue when combined with react-native-webview on iOS.

When rendering a webview that has a video player, if the user enters fullscreen and then rotates the device, Dimensions.get('window') return switched values (width -> height, height ->width). For some reason, Dimensions.get('screen') work just fine.

As far as I know, we can only wait and stay with 0.61.x . This hasn’t brought a lot of attention because most apps use locked rotation and I guess rarely use webviews.

I also encountered this issue while handling rotation detection with a web view - it happens immediately on the first render. In my case, a call to Orientation.lockToLandscape() or Orientation.lockToPortrait() would be invoked before retrieving the window dimensions via Dimensions.get("window"). The dimension values, however, would not update after the orientation change.

The packages used:

react-native@0.63.2
react-native-webview@10.4.1
react-native-orientation-locker@1.2.0

A strange behavior worth noting: When changing to a separate tab in my app (using react-navigation-tabs), locking the orientation portrait->landscape->portrait, then returning to the web view tab, the Dimension API suddenly begins working flawlessly. I would speculate that the issue only occurs after some sort of “initialization” state.

Also, referencing this issue from react-native-orientation-locker regarding this. There are a few potentially helpful workarounds available.