diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java index a5399a2e2..b10c2e6ce 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java @@ -521,8 +521,8 @@ public class UIViewOperationQueue { private ArrayList mOperations = new ArrayList<>(); @GuardedBy("mNonBatchedOperationsLock") private ArrayDeque mNonBatchedOperations = new ArrayDeque<>(); - private @Nullable NotThreadSafeViewHierarchyUpdateDebugListener mViewHierarchyUpdateDebugListener; + private boolean mIsDispatchUIFrameCallbackEnqueued = false; public UIViewOperationQueue( ReactApplicationContext reactContext, @@ -779,17 +779,41 @@ public class UIViewOperationQueue { } }); } + + // In the case where the frame callback isn't enqueued, the UI isn't being displayed or is being + // destroyed. In this case it's no longer important to align to frames, but it is imporant to make + // sure any late-arriving UI commands are executed. + if (!mIsDispatchUIFrameCallbackEnqueued) { + UiThreadUtil.runOnUiThread( + new Runnable() { + @Override + public void run() { + flushPendingBatches(); + } + }); + } } /* package */ void resumeFrameCallback() { + mIsDispatchUIFrameCallbackEnqueued = true; ReactChoreographer.getInstance() .postFrameCallback(ReactChoreographer.CallbackType.DISPATCH_UI, mDispatchUIFrameCallback); } /* package */ void pauseFrameCallback() { - + mIsDispatchUIFrameCallbackEnqueued = false; ReactChoreographer.getInstance() .removeFrameCallback(ReactChoreographer.CallbackType.DISPATCH_UI, mDispatchUIFrameCallback); + flushPendingBatches(); + } + + private void flushPendingBatches() { + synchronized (mDispatchRunnablesLock) { + for (int i = 0; i < mDispatchUIRunnables.size(); i++) { + mDispatchUIRunnables.get(i).run(); + } + mDispatchUIRunnables.clear(); + } } /** @@ -825,12 +849,7 @@ public class UIViewOperationQueue { Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); } - synchronized (mDispatchRunnablesLock) { - for (int i = 0; i < mDispatchUIRunnables.size(); i++) { - mDispatchUIRunnables.get(i).run(); - } - mDispatchUIRunnables.clear(); - } + flushPendingBatches(); ReactChoreographer.getInstance().postFrameCallback( ReactChoreographer.CallbackType.DISPATCH_UI, this);