react-native
                                
                                 react-native copied to clipboard
                                
                                    react-native copied to clipboard
                            
                            
                            
                        [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.
- Build a simple Android app with unlocked orientation (that is, allow all orientations)
- Use Dimensions API: Dimensions.get('window')andDimensions.addEventListener(...). For example, registering these on the root's component mount.
- Rotate the device a few times and confirm Dimensions is firing the event
- Mount a <WebView />component and rotate a few times
- Unmount the <WebView />component
- 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
Update: Tried downgrading and this is definitely a 0.63.1 issue... I still don't know why would WebViews trigger it though.
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.
Seeing lots of recent issues on this: #29323 #29290 #29105 Let's try to get all the info into one issue. Do you think there's overlap there in any of those issues?
Those issues really seem related, although they seem to be getting the issue right away. From my testing, it only happens after opening a webview (or perhaps the webview uses something else that triggers it, such as a Modal/Dialog or screen navigation).
This issue seems quite critical, any work-arounds at least?
I have the same issue on my Application. Anyone has any workaround here ?
There may definitely be some overlap with the issue we're having. Our app includes a module that uses UIWebView in its operation. I've not checked other screens, but the incorrect dimensions are definitely occurring on the screen that uses this library. We can't update the module to WKWebView so can't check if that also causes the issue, but there could be a connection.
For me, this is happening on Android only, so I wouldn't know about UIWebView.
I'm guessing most people implemented their app without rotation support, so they are not aware of this issue at all. For me, this is quite critical and needs urgent attention.
Oh yes, you're right! We're having this issue on Android only, so it obviously has nothing to do with the iOS stuff. I'm definitely having one of those days... :)
It's a complete blocker for us upgrading as well, unfortunately.
@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.
Thanks a lot @cristianoccazinsp currently I only have weeekends to do opensource, unluckily I never worked with the ReactNative Dimensions SourceCode
My todos for next weeks are finishing https://github.com/facebook/react-native/pull/29117 and https://github.com/facebook/react-native/pull/29070
Then I can take a look at this. The first step in solving all bugs is creating a Minimum Reproducible Example and start understanding all not related APIs.
Does it really need Webview and react-navigation to reproduce? What is really causing this issue? Is this issue caused from the JavaScript of Java ReactNative API?
Mount a <WebView /> component and rotate a few times
What does Mounting, Unmounting, Rotating actually do to stop the event to fire? Can we get insight on the source-code and how does WebView, ReactNavigation affect the rotation/event firing?
But N.1, reproducing the bug without React-Navigation and Webview, because this exclude a large amount of sourcecode from investigation
It is much easier to remove a prop style and notice that the issue still reproduce, rather then investigate all the JavaScript and Java API behind style prop, debug it and understand that the prop is not relevant for this issue
So the easiest way to solve the bug is by testing the RN API and see the difference in the reproduction.
I bookmarked and follow this issue, I'll try to solve it once finishing https://github.com/facebook/react-native/pull/29117 and https://github.com/facebook/react-native/pull/29070 are completed. Thanks. I wish you a good day
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.
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.
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:
[email protected]
[email protected]
[email protected]
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.
Thanks for the insight @TGibsonn . For now, we have decided to roll back to RN 0.62.2 until this and other major bugs are resolved.
Is there anything new regarding this issue? Anything we can do in order to help? This seems to block teams wanting to update to latest RN version right now :/
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.
@fabriziobertoglio1987 Can't provide too much information at the moment, but I can confirm we're also getting this issue for Android only on 0.63.2. We'll be having to rollback the RN update 😞 . Happy to provide info where I can.
We do use react-native-webview, but it's not loaded on screen before we get this issue. I wonder if pointing out this library though is just a red herring.
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.
possibly related - the 'change' listener doesn't fire at all 0.63.3 iOS Simulator, traced it from onLayout not firing on orientation change.
@react-native-bot This is the really critical issue which breaks all Android orientation related styling in apps. When this can be reviewed by maintainers? Thanks...
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 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!!!
https://github.com/facebook/react-native/blob/17a8737ecb68f61a14f54bf0e2efeb618f97d326/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java#L81-L87
https://github.com/facebook/react-native/blob/17a8737ecb68f61a14f54bf0e2efeb618f97d326/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java#L117-L126
Here are the changes in [email protected] that relate to the the dimensions module (I confirmed that this regression starts to occur in the first 63 release).
Changed
- Only set dimensions if the window attributes change (35c6bb9ac0 by @cpojer)
- Only update dimensions in ReactRootView if they've changed (cc3e27d484 by @ejanzer)
- Don't emit dimensions update event on initial load (383934a06e by @ejanzer)
Fixed
- Fix bug in updating dimensions in JS (bef845ffd5 by @ejanzer)
The change from cpojer seems like a red herring, because it only touches one of the dimension hooks in the JS layer. This bug happens on every thing that uses the dimensions module, not just one hook, so it can't be that.
@ejanzer does anything jump out at you as an obvious reason why rendering a webview in [email protected] might cause the Dimensions module to stop firing its addEventListener callbacks? Any suggestions for potential workarounds?
I forked react-native from the [email protected] 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?
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
Can confirm that the PR from @ajpaulingalls fixes this issue for me. It's clearly a bug in ReactRootView where the state in DisplayMetricsHolder isn't getting updated before the business logic runs, which is using stale state and causes actual dimensions change callbacks to get missed.
Thanks Paul!
The fix for this is checked into the master branch (thank you @ajpaulingalls and @ejanzer) and will naturally make its way into the first [email protected] release candidates. If you want it to be included in the future [email protected] patch release, please upvote the comment linked below.
https://github.com/react-native-community/releases/issues/212#issuecomment-725612630
@luisnaranjo733 Thanks for letting us know that the fix has been added to 0.63.4. Would you possibly know who I can get in contact with to get WalmartLabs hosted Android Maven repo updated? https://mvnrepository.com/artifact/com.walmartlabs.ern/react-native
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.