Flutter: avoid UI freeze when massive Database operation is in progress

The problem is that Flutter is Single Threaded, so once you get a heavy process running, your Single Thread will block anything else.

The solution is to be smart on how to use that Single Thread.

Dart will have an Event Queue with a bunch of Futures waiting to be processed. Once the Dart engine sees an await it will let another Future grab hold of the Single Thread and let it run. This way, one Future will run at a time inside an Isolate.

So if we get smart about it, we let everyone play at it's own time, in other words, we break down our tasks into smaller tasks, so the Dart engine won't starve other Futures, and all the processes awaiting for running can have their time.

The equivalent for your code would be something like this (assuming the for is what takes lots of time to execute, because of a large collection, and not it's individual steps):

static Future<void> _parseResponse(xml.XmlElement elements) async {
  Database db = await MyDatabaseHelper.openConnection();
  db.transaction((tx) async {
    Batch batch = tx.batch();
    for (xml.XmlElement oi in elements.children) {      
      await Future(() {
        int id = int.parse(oi.findElements("ID").first.text);
        String name = oi.findElements("NAME").first.text;

         DatabaseHelper.insertElement(
          tx,
          id: id,
          name: name,
         );
      );
    }

    batch.commit(noResult: true);
  });
}

This will fragment each step of your for loop into a Future, so at each step your UI will have the opportunity to execute whatever it needs to execute to keep your animations smooth. Keep in mind though that this will have the side effect of slowing down _parseResponse as putting each for step into the Future Event Queue will have an additional cost, so you might want to optimize this further for your particular use case.