Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why network requests in Flutter doesn't block the UI

Tags:

flutter

dart

I know Dart is Single Threaded, flutter is also, so if I do some heavy task, it will block the UI event queue, but a network request takes several seconds without blocking the UI.

so, why Socket does not block UI? What bothers me is why the socket does not block the UI, but the heavy task does, Although they all asynchronous task.

for example, this code will block UI

@override
void initState() {
super.initState();
Future((){
  var result;
  for (var i = 0; i < 1000000; ++i) {
    result = 'result is $i';
  }
  print(result);
});

this code is normal HTTP request,it won't block UI

get() async {
  var httpClient = new HttpClient();
  var uri = new Uri.http(
      'example.com', '/path1/path2', {'param1': '42', 'param2': 'foo'});
  var request = await httpClient.getUrl(uri);
  var response = await request.close();
  var responseBody = await response.transform(UTF8.decoder).join();
}

The reason why the socket does not block the UI is to split the request process into multiple parts? and send these part to the current microtask queue,As this answer says:

https://stackoverflow.com/a/56783713/6540631

so, does anyone know how sockets are implemented asynchronously? Whether socket use Isolate, Future, or other means?The socket run on UI thread, or other thread?

and, If I have to perform heavy tasks that cannot be split in the UI thread(such as text layout), what should I do?


Supplementary explanation:

I know how to use Future and Isolate, but I encountered a problem.

if use TextPainter.layout in isolate will get a compiler error native function not found.

I need layout many words and it takes a long time (100ms+), it will block UI thread.

What should I do?

https://github.com/flutter/flutter/issues/30604

The Flutter engine native APIs for the UI package is only available in the primary isolate.

https://github.com/flutter/flutter/issues/30604#issuecomment-481380706

right now you would have to write your own line-breaking logic - perhaps as a plugin. We don't currently have any API for doing text layout in a separate isolate. @GaryQian might have some other idea about this too.

https://github.com/flutter/flutter/issues/30604#issuecomment-526013977

so I have to do text layout in UI thread(use TextPainter ), although write a plugin can solve this problem and it work well, Is there an easier way?

I guess I can get help from the implementation details of the socket, so I raised this question.

like image 822
Lucky Dog Avatar asked Sep 30 '19 03:09

Lucky Dog


People also ask

Is await blocking a flutter?

Await calls are non-blocking. The way this works is, while Dart is single-threaded, some Dart code delegate their implementation to the Dart VM. Things like file reads or HTTP requests are performed outside of Dart (either by the browser or in c++), in a different thread.

Does await block the main thread flutter?

As per this answer and this article, await is supposed to interrupt code execution and actually wait for the future to complete and then continue executing the rest of the code sequentially. It also suggests that this might block the main thread, which is only logical in that case.


1 Answers

In dart, Network calls are asnycronous nature and returns Future. When anything is asynchronous, it runs in the background and returns result or response on task completion. It's quite similar to Promise in javascript. Here are list of key terms related to Async in dart taken from Official Docs.

Key terms:


synchronous operation: A synchronous operation blocks other operations from executing until it completes.
synchronous function: A synchronous function only performs synchronous operations.
asynchronous operation: Once initiated, an asynchronous operation allows other operations to execute before it completes.
asynchronous function: An asynchronous function performs at least one asynchronous operation and can also perform synchronous operations.

In your case, you have used Future but function must yield via await to allow other operations to execute in the isolate. If you don't yield, it will block the UI thread. That's exactly you got in the first code block and UI gone blocked. You have used Future but the computation still goes synchronous in it. There is a precise Post here for more reference.
like image 156
Kiran Maniya Avatar answered Oct 23 '22 04:10

Kiran Maniya