Где разместить функцию для срабатывания при выходе / остановке / закрытии приложения flutter / dart? - PullRequest
2 голосов
/ 08 июля 2020

У меня есть простой пример кода сервера gRP C приветствия, написанный на go и экспортированный как C библиотека, которую я пытаюсь запустить с помощью приложения flutter, используя go -flutter настольный движок через ffi и dart Isolates.

Я создал функцию StopGrpc(), которая работает, если я вызываю ее для остановки сервера gRP C.

Но если я не делаю этого вручную сначала активируйте функцию StopGrpc() перед выходом из приложения, я продолжаю получать следующее waiting for isolates _startGrpc to check in, которое никогда не заканчивается, и мне нужно принудительно закрыть приложение.

An Observatory debugger and profiler on Flutter test device is available at: http://127.0.0.1:50300/
go-flutter: closing application
Attempt:11 waiting for isolate _startGrpc to check in
Attempt:12 waiting for isolate _startGrpc to check in

Вот полная копия файла lib/main.dart для справки:

/// Example code from: https://codingwithjoe.com/dart-fundamentals-isolates/
/// Flutter example code from: https://gist.github.com/jebright/a7086adc305615aa3a655c6d8bd90264
import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:isolate';

import 'dart:ffi';

// import 'package:ffi/ffi.dart';

// -- Normal gRPC server type definitions --
typedef startgrpc_func = void Function();
typedef StartGrpc = void Function();

typedef stopgrpc_func = void Function();
typedef StopGrpc = void Function();

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Isolate Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Isolates'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Isolate _isolate;
  bool _running = false;
  static int _counter = 0;
  String notification = "";
  ReceivePort _receivePort;

  void _start() async {
    _running = true;
    _receivePort = ReceivePort();
    _isolate = await Isolate.spawn(_startGrpc, _receivePort.sendPort);
    _receivePort.listen(_handleMessage, onDone: () {
      print("done!");
    });
  }

  static void _checkTimer(SendPort sendPort) async {
    Timer.periodic(new Duration(seconds: 1), (Timer t) {
      _counter++;
      String msg = 'notification ' + _counter.toString();
      print('SEND: ' + msg);
      sendPort.send(msg);
    });
  }

  static void _startGrpc(SendPort sendPort) async {
    // -- Normal gRPC server start code --
    final greeter = DynamicLibrary.open('assets/greeter.so');
    final void Function() startGrpc = greeter
        .lookup<NativeFunction<Void Function()>>('StartGrpc')
        .asFunction();
    String msg = "Started gRPC server...";
    sendPort.send(msg);
    startGrpc();
  }

  static void _stopGrpc() async {
    // -- Normal gRPC server stop code --
    final greeter = DynamicLibrary.open('assets/greeter.so');
    final void Function() stopGrpc = greeter
        .lookup<NativeFunction<Void Function()>>('StopGrpc')
        .asFunction();
    // String msg = "Stoped gRPC server...";
    // sendPort.send(msg);
    stopGrpc();
  }

  void _handleMessage(dynamic data) {
    print('RECEIVED: ' + data);
    setState(() {
      notification = data;
    });
  }

  void _stop() {
    if (_isolate != null) {
      setState(() {
        _running = false;
        notification = '';
      });
      _stopGrpc();
      _receivePort.close();
      _isolate.kill(priority: Isolate.immediate);
      _isolate = null;
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              notification,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _running ? _stop : _start,
        tooltip: _running ? 'Timer stop' : 'Timer start',
        child: _running ? new Icon(Icons.stop) : new Icon(Icons.play_arrow),
      ),
    );
  }
}

Если я сначала вызываю StopGrpc(), чтобы остановить сервер gRP C, а затем закрывать приложение, приложение завершает работу без каких-либо проблем.

Обычный выход выглядит как это в консоли отладки:

An Observatory debugger and profiler on Flutter test device is available at: http://127.0.0.1:50300/
Greet function was invoked with greeting:<first_name:"Satinder" last_name:"Grewal" > 
flutter: done!
go-flutter: closing application
Lost connection to device.
hover: App 'flutter_isolates' exited.
hover: Closing the flutter attach sub process..

Итак, мне нужно знать, где разместить StopGrpc() функцию для запуска при закрытии / выходе из приложения.

Кто-нибудь, пожалуйста, скажите мне, как я могу запускать функцию остановки сервера при выходе приложение?

Это код go -grp c, который я компилирую для этого go -flutter-приложения как C библиотеку: https://github.com/satindergrewal/flutter-practice/blob/master/go_dart_ffi_c_shared/greet/greet_server/server.go

И это код флаттера, который я использую для тестирования изоляторов флаттера: https://github.com/satindergrewal/flutter-practice/tree/master/flutter_isolates

Я уже просил помощи у go -flutter и они указали мне, чтобы я спросил в справочных каналах флаттера / флаттера.

Был бы очень признателен за помощь по этому поводу.

Спасибо, Сатиндер

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...