mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Make missing parent view state in updateLayout a soft error (#49951)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49951 We previously fixed Differentiator generating an incorrect parentTag (https://github.com/facebook/react-native/pull/48055), but this can lead to crashes in Android UI due to reordering that happens in the Android mounting layer. While we have an experiment to disable this reordering (https://github.com/facebook/react-native/pull/46702) this currently has a negative performance impact which needs to be addressed. As a mitigation, we can make the lookup of parentTag's ViewManager state nullable. We only require this to support `needsCustomLayoutForChildren`, which is not commonly used, and seems acceptable to drop in this scenario. Changelog: [Android][Changed] Do not crash when parent view state can't be found Reviewed By: NickGerleman Differential Revision: D70966621 fbshipit-source-id: 33d0b6a90860788a4c9a8c6cea36c2c72c1392e1
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1482dd9e99
commit
ade41c851b
+9
-2
@@ -833,9 +833,16 @@ public class SurfaceMountingManager {
|
||||
parent.requestLayout();
|
||||
}
|
||||
|
||||
ViewState parentViewState = getViewState(parentTag);
|
||||
// TODO T212247085: Make this non-nullable again after rolling out
|
||||
// disableMountItemReorderingAndroid
|
||||
ViewState parentViewState = getNullableViewState(parentTag);
|
||||
IViewGroupManager<?> parentViewManager = null;
|
||||
if (parentViewState.mViewManager != null) {
|
||||
if (parentViewState == null) {
|
||||
ReactSoftExceptionLogger.logSoftException(
|
||||
ReactSoftExceptionLogger.Categories.SURFACE_MOUNTING_MANAGER_MISSING_VIEWSTATE,
|
||||
new ReactNoCrashSoftException(
|
||||
"Unable to find viewState for tag: " + parentTag + " for updateLayout"));
|
||||
} else if (parentViewState.mViewManager != null) {
|
||||
parentViewManager = (IViewGroupManager) parentViewState.mViewManager;
|
||||
}
|
||||
if (parentViewManager == null || !parentViewManager.needsCustomLayoutForChildren()) {
|
||||
|
||||
+38
-20
@@ -22,6 +22,7 @@ import com.facebook.react.fabric.mounting.SurfaceMountingManager;
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* This class represents a batch of {@link MountItem}s, represented directly as int buffers to
|
||||
@@ -199,7 +200,7 @@ final class IntBufferBatchMountItem implements BatchMountItem {
|
||||
public String toString() {
|
||||
try {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(String.format("IntBufferBatchMountItem [surface:%d]:\n", mSurfaceId));
|
||||
s.append(String.format(Locale.ROOT, "IntBufferBatchMountItem [surface:%d]:\n", mSurfaceId));
|
||||
int i = 0, j = 0;
|
||||
while (i < mIntBufferLen) {
|
||||
int rawType = mIntBuffer[i++];
|
||||
@@ -211,49 +212,65 @@ final class IntBufferBatchMountItem implements BatchMountItem {
|
||||
j += 3;
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"CREATE [%d] - layoutable:%d - %s\n",
|
||||
mIntBuffer[i++], mIntBuffer[i++], componentName));
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
componentName));
|
||||
} else if (type == INSTRUCTION_DELETE) {
|
||||
s.append(String.format("DELETE [%d]\n", mIntBuffer[i++]));
|
||||
s.append(String.format(Locale.ROOT, "DELETE [%d]\n", mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_INSERT) {
|
||||
s.append(
|
||||
String.format(
|
||||
"INSERT [%d]->[%d] @%d\n", mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++]));
|
||||
Locale.ROOT,
|
||||
"INSERT [%d]->[%d] @%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_REMOVE) {
|
||||
s.append(
|
||||
String.format(
|
||||
"REMOVE [%d]->[%d] @%d\n", mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++]));
|
||||
Locale.ROOT,
|
||||
"REMOVE [%d]->[%d] @%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_UPDATE_PROPS) {
|
||||
Object props = mObjBuffer[j++];
|
||||
String propsString =
|
||||
IS_DEVELOPMENT_ENVIRONMENT
|
||||
? (props != null ? props.toString() : "<null>")
|
||||
: "<hidden>";
|
||||
s.append(String.format("UPDATE PROPS [%d]: %s\n", mIntBuffer[i++], propsString));
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT, "UPDATE PROPS [%d]: %s\n", mIntBuffer[i++], propsString));
|
||||
} else if (type == INSTRUCTION_UPDATE_STATE) {
|
||||
StateWrapper state = (StateWrapper) mObjBuffer[j++];
|
||||
String stateString =
|
||||
IS_DEVELOPMENT_ENVIRONMENT
|
||||
? (state != null ? state.toString() : "<null>")
|
||||
: "<hidden>";
|
||||
s.append(String.format("UPDATE STATE [%d]: %s\n", mIntBuffer[i++], stateString));
|
||||
} else if (type == INSTRUCTION_UPDATE_LAYOUT) {
|
||||
int reactTag = mIntBuffer[i++];
|
||||
int parentTag = mIntBuffer[i++];
|
||||
int x = mIntBuffer[i++];
|
||||
int y = mIntBuffer[i++];
|
||||
int w = mIntBuffer[i++];
|
||||
int h = mIntBuffer[i++];
|
||||
int displayType = mIntBuffer[i++];
|
||||
int layoutDirection = mIntBuffer[i++];
|
||||
s.append(
|
||||
String.format(
|
||||
"UPDATE LAYOUT [%d]->[%d]: x:%d y:%d w:%d h:%d displayType:%d layoutDirection:"
|
||||
+ " %d\n",
|
||||
parentTag, reactTag, x, y, w, h, displayType, layoutDirection));
|
||||
Locale.ROOT, "UPDATE STATE [%d]: %s\n", mIntBuffer[i++], stateString));
|
||||
} else if (type == INSTRUCTION_UPDATE_LAYOUT) {
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE LAYOUT [%d]->[%d]: x:%d y:%d w:%d h:%d displayType:%d"
|
||||
+ " layoutDirection:%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_UPDATE_PADDING) {
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE PADDING [%d]: top:%d right:%d bottom:%d left:%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
@@ -263,6 +280,7 @@ final class IntBufferBatchMountItem implements BatchMountItem {
|
||||
} else if (type == INSTRUCTION_UPDATE_OVERFLOW_INSET) {
|
||||
s.append(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"UPDATE OVERFLOWINSET [%d]: left:%d top:%d right:%d bottom:%d\n",
|
||||
mIntBuffer[i++],
|
||||
mIntBuffer[i++],
|
||||
@@ -271,7 +289,7 @@ final class IntBufferBatchMountItem implements BatchMountItem {
|
||||
mIntBuffer[i++]));
|
||||
} else if (type == INSTRUCTION_UPDATE_EVENT_EMITTER) {
|
||||
j += 1;
|
||||
s.append(String.format("UPDATE EVENTEMITTER [%d]\n", mIntBuffer[i++]));
|
||||
s.append(String.format(Locale.ROOT, "UPDATE EVENTEMITTER [%d]\n", mIntBuffer[i++]));
|
||||
} else {
|
||||
FLog.e(TAG, "String so far: " + s.toString());
|
||||
throw new IllegalArgumentException(
|
||||
|
||||
Reference in New Issue
Block a user