Don't defer dispatching of events while paused
Reviewed By: astreet Differential Revision: D3186718 fb-gh-sync-id: 888c6e0cc0b52edbbc6b9e0cb285ce1a2d1bf987 fbshipit-source-id: 888c6e0cc0b52edbbc6b9e0cb285ce1a2d1bf987
This commit is contained in:
parent
8e7ea1179a
commit
860b7ddc35
|
@ -96,7 +96,7 @@ public class EventDispatcher implements LifecycleEventListener {
|
||||||
private Event[] mEventsToDispatch = new Event[16];
|
private Event[] mEventsToDispatch = new Event[16];
|
||||||
private int mEventsToDispatchSize = 0;
|
private int mEventsToDispatchSize = 0;
|
||||||
private @Nullable RCTEventEmitter mRCTEventEmitter;
|
private @Nullable RCTEventEmitter mRCTEventEmitter;
|
||||||
private volatile @Nullable ScheduleDispatchFrameCallback mCurrentFrameCallback;
|
private final ScheduleDispatchFrameCallback mCurrentFrameCallback;
|
||||||
private short mNextEventTypeId = 0;
|
private short mNextEventTypeId = 0;
|
||||||
private volatile boolean mHasDispatchScheduled = false;
|
private volatile boolean mHasDispatchScheduled = false;
|
||||||
private volatile int mHasDispatchScheduledCount = 0;
|
private volatile int mHasDispatchScheduledCount = 0;
|
||||||
|
@ -104,6 +104,7 @@ public class EventDispatcher implements LifecycleEventListener {
|
||||||
public EventDispatcher(ReactApplicationContext reactContext) {
|
public EventDispatcher(ReactApplicationContext reactContext) {
|
||||||
mReactContext = reactContext;
|
mReactContext = reactContext;
|
||||||
mReactContext.addLifecycleEventListener(this);
|
mReactContext.addLifecycleEventListener(this);
|
||||||
|
mCurrentFrameCallback = new ScheduleDispatchFrameCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,42 +119,37 @@ public class EventDispatcher implements LifecycleEventListener {
|
||||||
event.getEventName(),
|
event.getEventName(),
|
||||||
event.getUniqueID());
|
event.getUniqueID());
|
||||||
}
|
}
|
||||||
|
// If the host activity is paused, the frame callback may not be currently
|
||||||
|
// posted. Ensure that it is so that this event gets delivered promptly.
|
||||||
|
mCurrentFrameCallback.maybePostFromNonUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHostResume() {
|
public void onHostResume() {
|
||||||
UiThreadUtil.assertOnUiThread();
|
UiThreadUtil.assertOnUiThread();
|
||||||
Assertions.assumeCondition(mCurrentFrameCallback == null);
|
|
||||||
|
|
||||||
if (mRCTEventEmitter == null) {
|
if (mRCTEventEmitter == null) {
|
||||||
mRCTEventEmitter = mReactContext.getJSModule(RCTEventEmitter.class);
|
mRCTEventEmitter = mReactContext.getJSModule(RCTEventEmitter.class);
|
||||||
}
|
}
|
||||||
|
mCurrentFrameCallback.maybePost();
|
||||||
mCurrentFrameCallback = new ScheduleDispatchFrameCallback();
|
|
||||||
ReactChoreographer.getInstance()
|
|
||||||
.postFrameCallback(ReactChoreographer.CallbackType.TIMERS_EVENTS, mCurrentFrameCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHostPause() {
|
public void onHostPause() {
|
||||||
clearFrameCallback();
|
stopFrameCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHostDestroy() {
|
public void onHostDestroy() {
|
||||||
clearFrameCallback();
|
stopFrameCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCatalystInstanceDestroyed() {
|
public void onCatalystInstanceDestroyed() {
|
||||||
clearFrameCallback();
|
stopFrameCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearFrameCallback() {
|
private void stopFrameCallback() {
|
||||||
UiThreadUtil.assertOnUiThread();
|
UiThreadUtil.assertOnUiThread();
|
||||||
if (mCurrentFrameCallback != null) {
|
mCurrentFrameCallback.stop();
|
||||||
mCurrentFrameCallback.stop();
|
|
||||||
mCurrentFrameCallback = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -229,7 +225,7 @@ public class EventDispatcher implements LifecycleEventListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ScheduleDispatchFrameCallback implements Choreographer.FrameCallback {
|
private class ScheduleDispatchFrameCallback implements Choreographer.FrameCallback {
|
||||||
|
private volatile boolean mIsPosted = false;
|
||||||
private boolean mShouldStop = false;
|
private boolean mShouldStop = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -237,14 +233,16 @@ public class EventDispatcher implements LifecycleEventListener {
|
||||||
UiThreadUtil.assertOnUiThread();
|
UiThreadUtil.assertOnUiThread();
|
||||||
|
|
||||||
if (mShouldStop) {
|
if (mShouldStop) {
|
||||||
return;
|
mIsPosted = false;
|
||||||
|
} else {
|
||||||
|
post();
|
||||||
}
|
}
|
||||||
|
|
||||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "ScheduleDispatchFrameCallback");
|
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "ScheduleDispatchFrameCallback");
|
||||||
try {
|
try {
|
||||||
moveStagedEventsToDispatchQueue();
|
moveStagedEventsToDispatchQueue();
|
||||||
|
|
||||||
if (!mHasDispatchScheduled) {
|
if (mEventsToDispatchSize > 0 && !mHasDispatchScheduled) {
|
||||||
mHasDispatchScheduled = true;
|
mHasDispatchScheduled = true;
|
||||||
Systrace.startAsyncFlow(
|
Systrace.startAsyncFlow(
|
||||||
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
||||||
|
@ -252,9 +250,6 @@ public class EventDispatcher implements LifecycleEventListener {
|
||||||
mHasDispatchScheduledCount);
|
mHasDispatchScheduledCount);
|
||||||
mReactContext.runOnJSQueueThread(mDispatchEventsRunnable);
|
mReactContext.runOnJSQueueThread(mDispatchEventsRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReactChoreographer.getInstance()
|
|
||||||
.postFrameCallback(ReactChoreographer.CallbackType.TIMERS_EVENTS, this);
|
|
||||||
} finally {
|
} finally {
|
||||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||||
}
|
}
|
||||||
|
@ -263,6 +258,36 @@ public class EventDispatcher implements LifecycleEventListener {
|
||||||
public void stop() {
|
public void stop() {
|
||||||
mShouldStop = true;
|
mShouldStop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void maybePost() {
|
||||||
|
if (!mIsPosted) {
|
||||||
|
mIsPosted = true;
|
||||||
|
post();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void post() {
|
||||||
|
ReactChoreographer.getInstance()
|
||||||
|
.postFrameCallback(ReactChoreographer.CallbackType.TIMERS_EVENTS, mCurrentFrameCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void maybePostFromNonUI() {
|
||||||
|
if (mIsPosted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should only hit this slow path when we receive events while the host activity is paused.
|
||||||
|
if (mReactContext.isOnUiQueueThread()) {
|
||||||
|
maybePost();
|
||||||
|
} else {
|
||||||
|
mReactContext.runOnUiQueueThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
maybePost();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DispatchEventsRunnable implements Runnable {
|
private class DispatchEventsRunnable implements Runnable {
|
||||||
|
|
Loading…
Reference in New Issue