skip to Main Content

In my code, after the button is pressed the method is called where there are calls to three functions with calculations and export to PDF file. One of the functions takes a field of the class as a parameter which is changed by moving a slider in the app. The problem is that the animation of pressing the button lags due to the calculations and export. Also, the CPU usage of the exe jumps up by 7% – 15%.

The method does not return anything and the result of its work is just PDF file, so I don’t need to wait until it finishes but just start it and care about other events.

I want to make the method compute in parallel or simultaneously, so it does not slow down the whole app and animation of pressing the button plays smoothly.

Attempts

I have tried to change the function type to Future and add async, but it didn’t help.

I have also tried to use Isolate.run. It works if I put only two functions inside of that, but if I add the third one which takes the field of the class as a parameter it stops working.

Here is the simplified look of the class and the method which is invoked after the button is pressed.

class Pattern{
    int scale = 10; //it's changed by slider

    void exportImage() {
        
        ImageBMP image = drawPattern(scale); //if I add this to Isolate it breakes
        
        var dividedImage = divideImage(image);
        
        createPDF(dividedImage);
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    Finally solved it by using Isolate.run and creating local variable for scale in the method.

    The final code looks something like that

    import 'dart:isolate';
    
    class Pattern{
        int scale = 10; //it's changed by slider
    
        void exportImage() {
        
            int l_scale = scale;
            
            Isolate.run
            (()
                {
                  ImageBMP image = drawPattern(l_scale); 
                  var dividedImage = divideImage(image);
                  createPDF(dividedImage);
                }
            );
        }
    }
    

    If someone can benefit from it:

    Same way can be used for methods. The method drawPattern in my code is different for every child of the Pattern class, but takes the same argument int scale and for quite long I couldn't put it in Isolate because it takes only static functions. The solution for that was to create a field in the Pattern class which would store the function and then in exportImage function create local variable similarly to what I did with scale. So finally my code looks like that

    import 'dart:isolate';
    
    class Pattern{
        int scale = 10; //it's changed by slider
        late ImageBMP Function(int) drawPattern;
    
        void exportImage() {
        
            int l_scale = scale;
            ImageBMP Function(int) l_drawPattern = drawPattern;
            
            Isolate.run
            (()
                {
                  ImageBMP image = l_drawPattern(l_scale); 
                  var dividedImage = divideImage(image);
                  createPDF(dividedImage);
                }
            );
        }
    }
    
    //example of child class
    class Square extends Pattern{
      Square() {
        drawPattern = drawSquare;
      }
    }
    //drawSquare is a top-level function which takes 'int scale' as argument
    

  2. Import foundation.dart which has the compute method :

    import 'package:flutter/foundation.dart';
    

    Then use compute within your exportImage method to do its work in the background.

    void exportImage() {
      compute((_) {
        ImageBMP image = createImage();
        var dividedImage = divideImage(image);
        createPDF(dividedImage);
      }, null);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search