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

add ReactRootView in RelativeLayout, will cause endless loop #19403

Closed
3 tasks done
killerJava opened this issue May 23, 2018 · 6 comments
Closed
3 tasks done

add ReactRootView in RelativeLayout, will cause endless loop #19403

killerJava opened this issue May 23, 2018 · 6 comments
Labels
Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@killerJava
Copy link

killerJava commented May 23, 2018

Environment

System:
OS: Windows 7 6.1
CPU: x64 Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz
Memory: 1.46 GB / 7.88 GB
IDEs:
Android Studio 3.0.1
Build #AI-171.4443003, built on November 10, 2017
JRE: 1.8.0_152-release-915-b01 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o

Steps to Reproduce

add ReactRootView in RelativeLayout, we see onMeasure code in ReactRootView:

1

updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec);

2

this method will call YGNodeCalculateLayout func in Yoga.cpp.

3

if the root node has changed, yoga set node has a new layout flag. reflect in YGJNI.CPP
obj->setFieldValue(hasNewLayoutField, true);
YGTransferLayoutDirection(root, obj);
root->setHasNewLayout(false);

4

this flag will cause to put node to mOperations, and wait to update:
mUIViewOperationQueue.enqueueUpdateLayout(
toUpdate.getNativeParent().getReactTag(),
tag,
x,
y,
toUpdate.getScreenWidth(),
toUpdate.getScreenHeight());

5

in NativeViewHierarchyManager class, updateLayout will call ReactRootView' requestLayout:
if (parent instanceof RootView) {
parent.requestLayout();
}

requestLayout -----> onMeasure, loop ...

because RelativeLayout will measure child twice, but the height is diffrent between two measures:
ReactRootView: onMeasure: width is 1080, height is 1728

ReactRootView: onMeasure: width is 1080, height is 1581

hope can fix this question in ReactRootView

Expected Behavior

not occur always call onMeasure func

Actual Behavior

always call onMeasure in ReactRootView,

RelativeLayout will measure child twice:
ReactRootView: onMeasure: width is 1080, height is 1728
ReactRootView: onMeasure: width is 1080, height is 1581

height changed, will call NativeViewHierarchyManager.updateLayout func, in this func, will
call ReactRootView.requestLayout, requestLayout will cause measue child, cause endless loop

@killerJava killerJava changed the title put ReactRootView in RelativeLayout, will cause endless loop add ReactRootView in RelativeLayout, will cause endless loop May 23, 2018
@react-native-bot
Copy link
Collaborator

Please run react-native info and update your issue.

@ethanleeX
Copy link

I have the same problem , I solve it by relpace relativelayout with linearlayout , but I don't think it is a good way, sometimes it may course overdraw

@hramos
Copy link
Contributor

hramos commented Jul 2, 2018

This issue can be improved by providing a small code sample that reproduces the issue.

@allenhsu
Copy link

allenhsu commented Aug 7, 2018

We've encountered this problem as well, I think the problem is that with RelativeLayout, if you have used something like layout_above (in our case, a container view above bottom bar), measure and onMeasure of ReactRootView will be called twice with different height.

The first time to calculate max height, the second time to calculate exact height. Since the container is set to match parent's size, the first time it's height is set to parent's height (screen height most of the time). The second time, it's parent's height minus bottom bar's height. Since the two heights are different, it triggers layout of RN components, this layout somehow triggered measure/layout of the app again. Thus, it becomes a dead loop.

We resolved this by using LinearLayout instead of RelativeLayout as well, but I think it can and should be fixed in ReactRootView.

My question is, why updateRootLayoutSpecs is called in onMeasure rather than in onLayout?

@stale
Copy link

stale bot commented Nov 13, 2018

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 "For Discussion" or "Good first issue" 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 Nov 13, 2018
@stale
Copy link

stale bot commented Nov 20, 2018

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 Nov 20, 2018
@facebook facebook locked as resolved and limited conversation to collaborators Nov 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
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

5 participants