Skip to content

Commit

Permalink
Fix bug where UIOperations aren't executed after hosting Activity is …
Browse files Browse the repository at this point in the history
…paused.

Summary:
When we hit the back button and unmount the ReactRootView, we tell JS to unmount the application root node, which causes JS to asynchronously come back and tell the UIManager to drop the corresponding root view.

This issue was that by the time JS gets back to us, we likely will have already paused the UIManager frame callback which means the view unmounting never actually happens: it just gets stuck in the queue.

The solution is to immediately execute batches when they are enqueued when the frame callback isn't running.

Reviewed By: lexs

Differential Revision: D3398958

fbshipit-source-id: 0de81061a97a119be4cb0b12d6f01c1cec8e8171
  • Loading branch information
astreet authored and Facebook Github Bot 4 committed Jun 9, 2016
1 parent 5ef3b47 commit eef03fd
Showing 1 changed file with 27 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,8 @@ public void execute() {
private ArrayList<UIOperation> mOperations = new ArrayList<>();
@GuardedBy("mNonBatchedOperationsLock")
private ArrayDeque<UIOperation> mNonBatchedOperations = new ArrayDeque<>();

private @Nullable NotThreadSafeViewHierarchyUpdateDebugListener mViewHierarchyUpdateDebugListener;
private boolean mIsDispatchUIFrameCallbackEnqueued = false;

public UIViewOperationQueue(
ReactApplicationContext reactContext,
Expand Down Expand Up @@ -779,17 +779,41 @@ public void run() {
}
});
}

// 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();
}
}

/**
Expand Down Expand Up @@ -825,12 +849,7 @@ public void doFrameGuarded(long frameTimeNanos) {
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);
Expand Down

0 comments on commit eef03fd

Please sign in to comment.