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:
Chris Hopman 2016-04-25 12:45:37 -07:00 committed by Facebook Github Bot 8
parent 8e7ea1179a
commit 860b7ddc35
1 changed files with 46 additions and 21 deletions

View File

@ -96,7 +96,7 @@ public class EventDispatcher implements LifecycleEventListener {
private Event[] mEventsToDispatch = new Event[16];
private int mEventsToDispatchSize = 0;
private @Nullable RCTEventEmitter mRCTEventEmitter;
private volatile @Nullable ScheduleDispatchFrameCallback mCurrentFrameCallback;
private final ScheduleDispatchFrameCallback mCurrentFrameCallback;
private short mNextEventTypeId = 0;
private volatile boolean mHasDispatchScheduled = false;
private volatile int mHasDispatchScheduledCount = 0;
@ -104,6 +104,7 @@ public class EventDispatcher implements LifecycleEventListener {
public EventDispatcher(ReactApplicationContext reactContext) {
mReactContext = reactContext;
mReactContext.addLifecycleEventListener(this);
mCurrentFrameCallback = new ScheduleDispatchFrameCallback();
}
/**
@ -118,42 +119,37 @@ public class EventDispatcher implements LifecycleEventListener {
event.getEventName(),
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
public void onHostResume() {
UiThreadUtil.assertOnUiThread();
Assertions.assumeCondition(mCurrentFrameCallback == null);
if (mRCTEventEmitter == null) {
mRCTEventEmitter = mReactContext.getJSModule(RCTEventEmitter.class);
}
mCurrentFrameCallback = new ScheduleDispatchFrameCallback();
ReactChoreographer.getInstance()
.postFrameCallback(ReactChoreographer.CallbackType.TIMERS_EVENTS, mCurrentFrameCallback);
mCurrentFrameCallback.maybePost();
}
@Override
public void onHostPause() {
clearFrameCallback();
stopFrameCallback();
}
@Override
public void onHostDestroy() {
clearFrameCallback();
stopFrameCallback();
}
public void onCatalystInstanceDestroyed() {
clearFrameCallback();
stopFrameCallback();
}
private void clearFrameCallback() {
private void stopFrameCallback() {
UiThreadUtil.assertOnUiThread();
if (mCurrentFrameCallback != null) {
mCurrentFrameCallback.stop();
mCurrentFrameCallback = null;
}
mCurrentFrameCallback.stop();
}
/**
@ -229,7 +225,7 @@ public class EventDispatcher implements LifecycleEventListener {
}
private class ScheduleDispatchFrameCallback implements Choreographer.FrameCallback {
private volatile boolean mIsPosted = false;
private boolean mShouldStop = false;
@Override
@ -237,14 +233,16 @@ public class EventDispatcher implements LifecycleEventListener {
UiThreadUtil.assertOnUiThread();
if (mShouldStop) {
return;
mIsPosted = false;
} else {
post();
}
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "ScheduleDispatchFrameCallback");
try {
moveStagedEventsToDispatchQueue();
if (!mHasDispatchScheduled) {
if (mEventsToDispatchSize > 0 && !mHasDispatchScheduled) {
mHasDispatchScheduled = true;
Systrace.startAsyncFlow(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
@ -252,9 +250,6 @@ public class EventDispatcher implements LifecycleEventListener {
mHasDispatchScheduledCount);
mReactContext.runOnJSQueueThread(mDispatchEventsRunnable);
}
ReactChoreographer.getInstance()
.postFrameCallback(ReactChoreographer.CallbackType.TIMERS_EVENTS, this);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
@ -263,6 +258,36 @@ public class EventDispatcher implements LifecycleEventListener {
public void stop() {
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 {