Getting the error, "Internal error: The Interpreter has already been closed." after calling dispose() to free up memory

Viewed 268

I'm using flutter platform channels to use tflite in java. The interpreters are memory heavy so when I exit the current screen/page I dispose the interpreters, but when I navigate back to the page I get the error:

E/flutter ( 7960): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: PlatformException(error, Internal error: The Interpreter has already been closed., null, java.lang.IllegalStateException: Internal error: The Interpreter has already been closed.

Here is a minimal example of what I am doing in flutter

class StyleTransfer extends StatefulWidget {
  final selectedImage;

  const StyleTransfer({
    Key key,
    this.selectedImage,
  }) : super(key: key);

  @override
  _StyleTransferState createState() => _StyleTransferState();
}

    class _StyleTransferState extends State<StyleTransfer> {
      static const platform = const MethodChannel("com.name.package/tflite_java");
    
    
      @override
      Future<void> dispose() async{
        Future.delayed(Duration.zero, () async{
          await platform.invokeMethod("DisposeInterpreter").then((value) => print(value));
        });
    
        super.dispose();
      }
      
      @override
      Widget build(BuildContext context) {
      ...
      ...
      }
    }

and this is the dispose function in java

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "com.name.package/tflite_java";
    protected Interpreter predictInterpreter;
    protected Interpreter transformInterpreter;
    protected Interpreter.Options interpreterOptions = new Interpreter.Options();

    private ImageSegmenter imageSegmenter;

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        try {
            interpreterOptions.setNumThreads(4);
            predictInterpreter = new Interpreter(loadModelFile("prediction_1.tflite"), interpreterOptions);
            transformInterpreter = new Interpreter(loadModelFile("transfer_1.tflite"), interpreterOptions);
        } catch (Exception e) {
            e.printStackTrace();
        }

        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL).setMethodCallHandler((call, result) -> {
            if (call.method.equals("StylePredict")){

                // irrelevant code removed for minimal example;
            }
            else if (call.method.equals("DisposeInterpreter")){
                String response = DisposeInterpreter();
                result.success(response);
            }
            // Note: this method is invoked on the main thread.
        });
    }

    

    private String DisposeInterpreter() {
        predictInterpreter.close();
        transformInterpreter.close();
        return "All Models closed";
    }
}

When I press back from the StyleTransfer page, I get the All Models closed message, so that is working, but when I go back to this page with a new image I get the above error:

E/MethodChannel#com.name.package/tflite_java( 7960): Failed to handle method call E/MethodChannel#com.name.package/tflite_java( 7960): java.lang.IllegalStateException: Internal error: The Interpreter has already been closed.

0 Answers
Related