Ship early ViewCommand dispatch everywhere
Summary: Early ViewCommand dispatch: ship the experiment everywhere on Android. Since ViewCommands are totally divorced from the commit cycle currently, and since they are inherently unsafe, we can create a separate queue for them and retry them if they fail with a specific category of exceptions. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D22173050 fbshipit-source-id: 494b7c6b5dfd2aec8ba77ae35d0d58d4d727b9b4
This commit is contained in:
Родитель
0a115d9c3f
Коммит
0b63c94648
|
@ -57,12 +57,6 @@ public class ReactFeatureFlags {
|
|||
*/
|
||||
public static boolean nullifyCatalystInstanceOnDestroy = false;
|
||||
|
||||
/**
|
||||
* Temporary flag. See UIImplementation: if this flag is enabled, ViewCommands will be queued and
|
||||
* executed before any other types of UI operations.
|
||||
*/
|
||||
public static boolean allowEarlyViewCommandExecution = false;
|
||||
|
||||
/**
|
||||
* This react flag enables a custom algorithm for the getChildVisibleRect() method in the classes
|
||||
* ReactViewGroup, ReactHorizontalScrollView and ReactScrollView.
|
||||
|
|
|
@ -683,10 +683,6 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
|||
@UiThread
|
||||
@ThreadConfined(UI)
|
||||
private List<DispatchCommandMountItem> getAndResetViewCommandMountItems() {
|
||||
if (!ReactFeatureFlags.allowEarlyViewCommandExecution) {
|
||||
return null;
|
||||
}
|
||||
|
||||
synchronized (mViewCommandMountItemsLock) {
|
||||
List<DispatchCommandMountItem> result = mViewCommandMountItems;
|
||||
if (result.isEmpty()) {
|
||||
|
@ -870,29 +866,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: if early ViewCommand dispatch ships 100% as a feature, this can be removed.
|
||||
// This try/catch catches Retryable errors that can only be thrown by ViewCommands, which
|
||||
// won't be executed here in Early Dispatch mode.
|
||||
try {
|
||||
mountItem.execute(mMountingManager);
|
||||
} catch (RetryableMountingLayerException e) {
|
||||
// It's very common for commands to be executed on views that no longer exist - for
|
||||
// example, a blur event on TextInput being fired because of a navigation event away
|
||||
// from the current screen. If the exception is marked as Retryable, we log a soft
|
||||
// exception but never crash in debug.
|
||||
// It's not clear that logging this is even useful, because these events are very
|
||||
// common, mundane, and there's not much we can do about them currently.
|
||||
if (mountItem instanceof DispatchCommandMountItem) {
|
||||
ReactSoftException.logSoftException(
|
||||
TAG,
|
||||
new ReactNoCrashSoftException(
|
||||
"Caught exception executing retryable mounting layer instruction: "
|
||||
+ mountItem.toString(),
|
||||
e));
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
mBatchedExecutionTime += SystemClock.uptimeMillis() - batchedExecutionStartTime;
|
||||
}
|
||||
|
@ -1027,15 +1001,9 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
|||
@AnyThread
|
||||
@ThreadConfined(ANY)
|
||||
private void dispatchCommandMountItem(DispatchCommandMountItem command) {
|
||||
if (ReactFeatureFlags.allowEarlyViewCommandExecution) {
|
||||
synchronized (mViewCommandMountItemsLock) {
|
||||
mViewCommandMountItems.add(command);
|
||||
}
|
||||
} else {
|
||||
synchronized (mMountItemsLock) {
|
||||
mMountItems.add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,7 +25,6 @@ import com.facebook.react.bridge.RetryableMountingLayerException;
|
|||
import com.facebook.react.bridge.SoftAssertions;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.modules.core.ReactChoreographer;
|
||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||
import com.facebook.systrace.Systrace;
|
||||
|
@ -596,7 +595,6 @@ public class UIViewOperationQueue {
|
|||
private final DispatchUIFrameCallback mDispatchUIFrameCallback;
|
||||
private final ReactApplicationContext mReactApplicationContext;
|
||||
|
||||
private final boolean mAllowViewCommandsQueue;
|
||||
private ArrayList<DispatchCommandViewOperation> mViewCommandOperations = new ArrayList<>();
|
||||
|
||||
// Only called from the UIManager queue?
|
||||
|
@ -637,7 +635,6 @@ public class UIViewOperationQueue {
|
|||
? DEFAULT_MIN_TIME_LEFT_IN_FRAME_FOR_NONBATCHED_OPERATION_MS
|
||||
: minTimeLeftInFrameForNonBatchedOperationMs);
|
||||
mReactApplicationContext = reactContext;
|
||||
mAllowViewCommandsQueue = ReactFeatureFlags.allowEarlyViewCommandExecution;
|
||||
}
|
||||
|
||||
/*package*/ NativeViewHierarchyManager getNativeViewHierarchyManager() {
|
||||
|
@ -709,22 +706,14 @@ public class UIViewOperationQueue {
|
|||
int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
|
||||
final DispatchCommandOperation command =
|
||||
new DispatchCommandOperation(reactTag, commandId, commandArgs);
|
||||
if (mAllowViewCommandsQueue) {
|
||||
mViewCommandOperations.add(command);
|
||||
} else {
|
||||
mOperations.add(command);
|
||||
}
|
||||
}
|
||||
|
||||
public void enqueueDispatchCommand(
|
||||
int reactTag, String commandId, @Nullable ReadableArray commandArgs) {
|
||||
final DispatchStringCommandOperation command =
|
||||
new DispatchStringCommandOperation(reactTag, commandId, commandArgs);
|
||||
if (mAllowViewCommandsQueue) {
|
||||
mViewCommandOperations.add(command);
|
||||
} else {
|
||||
mOperations.add(command);
|
||||
}
|
||||
}
|
||||
|
||||
public void enqueueUpdateExtraData(int reactTag, Object extraData) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче