Skip to content

Commit

Permalink
Make EventChannel survive hot restart on Android (flutter#4350)
Browse files Browse the repository at this point in the history
  • Loading branch information
mravn-google authored Nov 13, 2017
1 parent 6b5d8c9 commit bc3ac07
Showing 1 changed file with 23 additions and 12 deletions.
35 changes: 23 additions & 12 deletions shell/platform/android/io/flutter/plugin/common/EventChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,16 @@ public interface StreamHandler {
void onListen(Object arguments, EventSink events);

/**
* Handles a request to tear down an event stream.
* Handles a request to tear down the most recently created event stream.
*
* <p>Any uncaught exception thrown by this method will be caught by the channel
* implementation and logged. An error result message will be sent back to Flutter.</p>
*
* <p>The channel implementation may call this method with null arguments
* to separate a pair of two consecutive set up requests. Such request pairs
* may occur during Flutter hot restart. Any uncaught exception thrown
* in this situation will be logged without notifying Flutter.</p>
*
* @param arguments stream configuration arguments, possibly null.
*/
void onCancel(Object arguments);
Expand Down Expand Up @@ -162,17 +167,23 @@ public void onMessage(ByteBuffer message, final BinaryReply reply) {

private void onListen(Object arguments, BinaryReply callback) {
final EventSink eventSink = new EventSinkImplementation();
if (activeSink.compareAndSet(null, eventSink)) {
try {
handler.onListen(arguments, eventSink);
callback.reply(codec.encodeSuccessEnvelope(null));
} catch (RuntimeException e) {
activeSink.set(null);
Log.e(TAG + name, "Failed to open event stream", e);
callback.reply(codec.encodeErrorEnvelope("error", e.getMessage(), null));
}
} else {
callback.reply(codec.encodeErrorEnvelope("error", "Stream already active", null));
final EventSink oldSink = activeSink.getAndSet(eventSink);
if (oldSink != null) {
// Repeated calls to onListen may happen during hot restart.
// We separate them with a call to onCancel.
try {
handler.onCancel(null);
} catch (RuntimeException e) {
Log.e(TAG + name, "Failed to close existing event stream", e);
}
}
try {
handler.onListen(arguments, eventSink);
callback.reply(codec.encodeSuccessEnvelope(null));
} catch (RuntimeException e) {
activeSink.set(null);
Log.e(TAG + name, "Failed to open event stream", e);
callback.reply(codec.encodeErrorEnvelope("error", e.getMessage(), null));
}
}

Expand Down

0 comments on commit bc3ac07

Please sign in to comment.