mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-03 17:45:12 +08:00
Fix bug where UIOperations aren't executed after hosting Activity is 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
This commit is contained in:
committed by
Facebook Github Bot 4
parent
5ef3b47ede
commit
eef03fd552
@@ -521,8 +521,8 @@ public class UIViewOperationQueue {
|
||||
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,
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user