17
17
import java .util .List ;
18
18
import java .util .Map ;
19
19
import java .util .WeakHashMap ;
20
- import java .util .concurrent .ConcurrentHashMap ;
21
20
import java .util .concurrent .ExecutorService ;
22
21
import java .util .concurrent .Executors ;
23
22
import java .util .concurrent .ThreadFactory ;
@@ -41,21 +40,17 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler {
41
40
*
42
41
* <p>Reads and writes to this map must lock {@code handlersLock}.
43
42
*/
44
- @ NonNull
45
- private final ConcurrentHashMap <String , HandlerInfo > messageHandlers = new ConcurrentHashMap <>();
43
+ @ NonNull private final Map <String , HandlerInfo > messageHandlers = new HashMap <>();
46
44
47
45
/**
48
- * Maps a channel name to queue of task dispatchers. This queue is processed when the channel
49
- * handler is registered.
46
+ * Maps a channel name to an object that holds information about the incoming Dart message.
50
47
*
51
48
* <p>Reads and writes to this map must lock {@code handlersLock}.
52
49
*/
53
- @ NonNull
54
- private final ConcurrentHashMap <String , List <DelayedMessageInfo >> delayedTaskDispatcher =
55
- new ConcurrentHashMap <>();
50
+ @ NonNull private final Map <String , List <BufferedMessageInfo >> bufferedMessages = new HashMap <>();
56
51
57
52
@ NonNull private final Object handlersLock = new Object ();
58
- private boolean canDelayTasks = false ;
53
+ private boolean enableBufferingIncomingMessages = false ;
59
54
60
55
@ NonNull private final Map <Integer , BinaryMessenger .BinaryReply > pendingReplies = new HashMap <>();
61
56
private int nextReplyId = 1 ;
@@ -113,12 +108,12 @@ private static class HandlerInfo {
113
108
* Holds information that allows to dispatch a Dart message to a platform handler when it becomes
114
109
* available.
115
110
*/
116
- private static class DelayedMessageInfo {
111
+ private static class BufferedMessageInfo {
117
112
@ NonNull public final ByteBuffer message ;
118
113
int replyId ;
119
114
long messageData ;
120
115
121
- DelayedMessageInfo (@ NonNull ByteBuffer message , int replyId , long messageData ) {
116
+ BufferedMessageInfo (@ NonNull ByteBuffer message , int replyId , long messageData ) {
122
117
this .message = message ;
123
118
this .replyId = replyId ;
124
119
this .messageData = messageData ;
@@ -179,31 +174,17 @@ public void setMessageHandler(
179
174
}
180
175
}
181
176
Log .v (TAG , "Setting handler for channel '" + channel + "'" );
182
- synchronized (handlersLock ) {
183
- messageHandlers .put (channel , new HandlerInfo (handler , dartMessengerTaskQueue ));
184
- }
185
- runDelayedTasksForChannel (channel );
186
- }
187
177
188
- /**
189
- * Runs the tasks that handle messages received from Dart for the provided channel name.
190
- *
191
- * <p>The channel may not have associated tasks if it was registered prior to reciving the first
192
- * message from Dart.
193
- *
194
- * @param channel The channel name.
195
- */
196
- public void runDelayedTasksForChannel (@ NonNull String channel ) {
197
- LinkedList <DelayedMessageInfo > list ;
178
+ LinkedList <BufferedMessageInfo > list ;
198
179
synchronized (handlersLock ) {
199
- if (!delayedTaskDispatcher .contains (channel )) {
180
+ messageHandlers .put (channel , new HandlerInfo (handler , dartMessengerTaskQueue ));
181
+ if (!bufferedMessages .containsKey (channel )) {
200
182
return ;
201
183
}
202
- list = (LinkedList ) delayedTaskDispatcher .get (channel );
203
- delayedTaskDispatcher .remove (channel );
184
+ list = (LinkedList ) bufferedMessages .get (channel );
185
+ bufferedMessages .remove (channel );
204
186
}
205
- while (!list .isEmpty ()) {
206
- final DelayedMessageInfo info = list .poll ();
187
+ for (BufferedMessageInfo info : list ) {
207
188
dispatchMessageToQueue (
208
189
channel , messageHandlers .get (channel ), info .message , info .replyId , info .messageData );
209
190
}
@@ -216,8 +197,8 @@ public void runDelayedTasksForChannel(@NonNull String channel) {
216
197
* be initialized concurrently, and prior to the registration of the channel handlers. This
217
198
* implies that Dart may start sending messages while plugins are being registered.
218
199
*/
219
- public void enableDelayedTaskQueue () {
220
- canDelayTasks = true ;
200
+ public void enableBufferingIncomingMessages () {
201
+ enableBufferingIncomingMessages = true ;
221
202
}
222
203
223
204
@ Override
@@ -287,9 +268,9 @@ private void dispatchMessageToQueue(
287
268
message .limit (0 );
288
269
}
289
270
} finally {
290
- Trace .endSection ();
291
271
// This is deleting the data underneath the message object.
292
272
flutterJNI .cleanupMessageData (messageData );
273
+ Trace .endSection ();
293
274
}
294
275
};
295
276
final DartMessengerTaskQueue nonnullTaskQueue =
@@ -304,10 +285,11 @@ public void handleMessageFromDart(
304
285
Log .v (TAG , "Received message from Dart over channel '" + channel + "'" );
305
286
306
287
HandlerInfo handlerInfo ;
288
+ boolean messageDeferred ;
307
289
synchronized (handlersLock ) {
308
- if ( messageHandlers .contains (channel )) {
309
- handlerInfo = messageHandlers . get ( channel );
310
- } else if (canDelayTasks ) {
290
+ handlerInfo = messageHandlers .get (channel );
291
+ messageDeferred = ( enableBufferingIncomingMessages && handlerInfo == null );
292
+ if (messageDeferred ) {
311
293
// The channel is not defined when the Dart VM sends a message before the channels are
312
294
// registered.
313
295
//
@@ -316,15 +298,15 @@ public void handleMessageFromDart(
316
298
//
317
299
// In such cases, the task dispatchers are queued, and processed when the channel is
318
300
// defined.
319
- if (!delayedTaskDispatcher . contains (channel )) {
320
- delayedTaskDispatcher .put (channel , new LinkedList <>());
301
+ if (!bufferedMessages . containsKey (channel )) {
302
+ bufferedMessages .put (channel , new LinkedList <>());
321
303
}
322
- List <Runnable > delayedTaskQueue = delayedTaskDispatcher .get (channel );
323
- delayedTaskQueue .add (new DelayedMessageInfo (message , replyId , messageData ));
304
+ List <BufferedMessageInfo > buffer = bufferedMessages .get (channel );
305
+ buffer .add (new BufferedMessageInfo (message , replyId , messageData ));
324
306
}
325
307
}
326
- if (handlerInfo != null ) {
327
- dispatchMessageToQueue (handlerInfo , message , replyId , messageData );
308
+ if (! messageDeferred ) {
309
+ dispatchMessageToQueue (channel , handlerInfo , message , replyId , messageData );
328
310
}
329
311
}
330
312
0 commit comments