Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

introduce

Dart is a single-threaded model without the concept of multi-threading in Android, but that doesn’t mean asynism doesn’t exist. Asynchronous operations certainly exist in applications. Dart provides something similar to the concept of threads — ISOLATE. So there’s no concurrency, some people call it ISOLATE, threads like processes. The Android and Dart virtual machine models are as follows:

Isolate create

In DART, a primary ISOLATE is created by default after executing the main method at startup. How do you create a sub-ISOLATE to perform asynchronous tasks? The isolate provides its own static method spawn to create an ISOLATE. This method requires two mandatory parameters:

  • EntryPoint: Specifies the initial function to call in the generated ISOLATE.
  • Message: Parameter to receive in the entryPoint function, usually used to pass sendPort for ISOLATE communication.
void main(){
  Isolate.spawn(entryPoint, "message");
}

void entryPoint(String message){
  print(message);
}
Copy the code

Verify memory isolation

Once the sub-isolates are created, can we verify that the different isolates are memory isolated? The following describes how to declare a global NUM, assign num to the main isolate, print num values in the main isolate and sub-ISOLATE respectively. The console logs show that no num value can be obtained in the sub-isolate.

int num;

void main(){
  num = 1;
  Isolate.spawn(entryPoint, "message");
  print("main num $num");
}

void entryPoint(String message){
  print("entryPoint num $num");
}
Copy the code

Isolate communication

Like Android, where we use handlers to communicate with threads, let’s see how the ISOLATE in DART sends and receives data.

ReceivePort receivePort = ReceivePort(); receivePort.listen((message) { print(message); }); ReceivePort. SendPort. Send (" this is communication message "); receivePort.sendPort.send(1);Copy the code

Create a receiver ReceivePort, send messages using its sender, sendPort, and listen to receive the sent messages through ReceivePort’s Listen method. It is important to note that the data sent in SEND is of unlimited type.

The “message” parameter in spawn is usually sendport that is passed to the main ISOLATE to communicate between the different isolates. That is, I give you my sender and prepare a receiver to receive the message sent by the sender. When you need to send a message through the sender to send a message to me:

void main(){ ReceivePort receivePort = ReceivePort(); Isolate.spawn(entryPoint, receivePort.sendPort); receivePort.listen((message) { print(message); }); } void entryPoint(SendPort SendPort){// Simulate time-consuming operation future.delayed (Duration(seconds: 2),(){sendport.send (" Messages sent to you inside the subisolate "); }); }Copy the code

As shown in the figure, the Main ISOLATE received a message sent from the child ISOLATE 2 seconds later.

Two-way communication

It says that we can communicate with the main ISOLATE using the sender of the sub-isolate. Then we can communicate with the main ISOLATE using the sender of the sub-isolate using the main Isolate. The send method does not limit the type of data to be sent. Therefore, after receiving main ISOLATE data, you can send the sender of the sub-ISOLATE first, and then send other communication data:

void main(){ ReceivePort receivePort = ReceivePort(); Isolate.spawn(entryPoint, receivePort.sendPort); Receiveport. listen((message) {if(message is SendPort){print(" Main received the sender of subisolate "); Future.delayed(Duration(seconds: 1),(){message.send(" Main sends messages to subisolate "); }); }else{ print(message); }}); } void entryPoint(SendPort sendPort){ ReceivePort receivePort = ReceivePort(); Receiveport. listen((message) {print(" main received message: $message"); }); sendPort.send(receivePort.sendPort); Future.delayed(Duration(seconds: 2),(){sendport.send (" Messages sent to main from subisolate "); }); }Copy the code

As shown below, main first receives a sender from the sub-isolate and then sends a message to the sub-isolate using this sender, enabling two-way communication between both ends.

Receiveport.close () is always called when the receiver is no longer in use.

Status method of the ISOLATE

Suspended:

isolate.pause(isolate.pauseCapability);
Copy the code

Recovery:

isolate.resume(isolate.pauseCapability);
Copy the code

The end:

isolate.kill(priority: Isolate.immediate);
Copy the code