Zastanów się, jak programowo wyjść z aplikacji

107

Jak programowo zamknąć aplikację Flutter. Próbowałem wyskoczyć z jedynego ekranu, ale powoduje to czarny ekran.

Theo Bouwman
źródło

Odpowiedzi:

66

Na iOS

SystemNavigator.pop(): NIE DZIAŁA

exit(0): Działa, ale Apple może ZAWIESIĆ TWOJĄ APLIKACJĘ, ponieważ programowe zamykanie aplikacji jest sprzeczne z wytycznymi Apple Human Interface.


Dla Android

SystemNavigator.pop(): Działa i jest ZALECANY sposób zamykania aplikacji.

exit(0): Działa również, ale NIE ZALECA SIĘ, ponieważ natychmiast przerywa proces Dart VM i użytkownik może pomyśleć, że aplikacja właśnie się zawiesiła.

CopsOnRoad
źródło
1
Wygląda na SystemNavigator.pop()to, że nie działa pod emulatorem Androida. Aplikacja nadal działa w tle. Nie jestem więc pewien, czy będzie działać poprawnie na prawdziwym urządzeniu.
BambinoUA
2
@AleksTi Po prostu zamyka aplikację, nie zamyka procesu VM. Możesz spróbować exit(0)dla swoich potrzeb.
CopsOnRoad
SystemNavigator.pop()zamyka moją aplikację i wyświetla komunikat o awarii, exit(0)działa zgodnie z oczekiwaniami
Shanks
147

Poniżej działało idealnie ze mną w obu Androidi iOS, korzystałem exit(0)zdart:io

import 'dart:io';

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new ... (...),
          floatingActionButton: new FloatingActionButton(
            onPressed: ()=> exit(0),
            tooltip: 'Close app',
            child: new Icon(Icons.close),
          ), 
    );
  }

UPDATE, styczeń 2019 r. Preferowanym rozwiązaniem jest:

SystemChannels.platform.invokeMethod('SystemNavigator.pop');

Jak opisano tutaj

Hasan A Yousef
źródło
to nie t work for me... Ipróbowało dodać przycisku wyjścia do CupertinoTabScafold. Z () => exit (0), daje to pusty ekran z paskiem tabulacji.
Ricardo BRGWeb
3
To działa. Ale Apple zabrania przycisków niestandardowych wyjścia i prawdopodobnie odrzucić aplikację, jeśli masz jeden
Dima Rostopira
@HasanAYousef W moim rozwiązaniu otrzymuję wiadomość Undefined name SystemChannels
user_odoo
38

Możesz to zrobić za pomocą SystemNavigator.pop().

Collin Jackson
źródło
1
Na Androidzie i iOS nic się nie dzieje. Używanie exit(0);działa
Theo Bouwman
2
W systemie iOS SystemNavigator.popjest ignorowany, ponieważ wytyczne Apple dotyczące interfejsu ludzkiego stanowią, że aplikacje nie powinny same się wyłączać. Na Androidzie powinno działać i jest preferowane w stosunku do dart:iometody wyjścia wywołania . Rozważ zgłoszenie problemu: github.com/flutter/flutter/issues/new
Collin Jackson
Każdy pomysł na iOS, jak możemy zrobić we flutter?
iPatel
@iPatel Możesz użyć exit (0) dla iOS, to wszystko.
CopsOnRoad
Hej, ale co z odrzuceniem; (jak powiedziałeś w powyższym komentarzu
iPatel
32

Odpowiedzi są już dostępne, ale nie kopiuj ich wklejania do bazy kodu, nie wiedząc, co robisz:

Jeśli używasz SystemChannels.platform.invokeMethod('SystemNavigator.pop');notatki, dokument wyraźnie wspomina:

Nakazuje nawigatorowi systemowemu usunięcie tego działania ze stosu i powrót do poprzedniego działania.

W systemie iOS wywołania tej metody są ignorowane, ponieważ wytyczne Apple dotyczące interfejsu ludzkiego stanowią, że aplikacje nie powinny same się zamykać.

Możesz użyć exit(0). A to natychmiast zakończy proces Dart VM z podanym kodem zakończenia. Ale pamiętaj, że doktor mówi:

To nie czeka na zakończenie jakichkolwiek operacji asynchronicznych. Dlatego użycie wyjścia może spowodować utratę danych.

W każdym razie doktor również zauważył SystemChannels.platform.invokeMethod('SystemNavigator.pop');:

Ta metoda powinna być preferowana w stosunku do wywoływania metody wyjścia dart: io, ponieważ ta ostatnia może spowodować, że platforma bazowa będzie działać tak, jakby aplikacja uległa awarii.

Więc pamiętaj, co robisz.

Blasanka
źródło
12
Napisałeś tyle sprytnych notatek, ale ... jaki jest właściwy sposób programowego wyjścia z aplikacji bez potencjalnego zawieszenia w iOS, jak opisano poniżej?
BambinoUA
6

Wolę używać

 Future.delayed(const Duration(milliseconds: 1000), () {
        SystemChannels.platform.invokeMethod('SystemNavigator.pop');
      });

Chociaż wyjście (0) również działa, ale aplikacja zamyka się nagle i nie wygląda ładnie, wygląda na to, że aplikacja uległa awarii.

 Future.delayed(const Duration(milliseconds: 1000), () {
       exit(0);
      });
Ayan Bhattacharjee
źródło
2

To zadziałało dla mnie;

import 'dart:io';

@override
Widget build(BuildContext context) {
  return new Scaffold(
    appBar: new AppBar(
      title: new Text(widget.title),
    ),
    body: new ... (...),
      floatingActionButton: new FloatingActionButton(
        onPressed: ()=> exit(0),
        tooltip: 'Close app',
        child: new Icon(Icons.close),
      ), 
  );
}
Hermana
źródło
1

możesz to nazwać, sprawdzając warunek zależny od platformy. wykonuj różne czynności po kliknięciu dla Androida i iOS.

    import 'dart:io' show Platform;
    import 'package:flutter/services.dart';

           

           RaisedButton(
                onPressed: () {
                  if (Platform.isAndroid) {
                    SystemNavigator.pop();
                  } else if (Platform.isIOS) {
                    exit(0);
                  }
                },
              child: Text("close app"),
            )
shirsh shukla
źródło