220

How can I programmatically close a Flutter application. I've tried popping the only screen but that results in a black screen.

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
Dirk
  • 3,095
  • 4
  • 19
  • 37

12 Answers12

219

Below worked perfectly with me in both Android and iOS, I used exit(0) from dart: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 Jan 2019 Preferable solution is:

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

As described here

tim-montague
  • 16,217
  • 5
  • 62
  • 51
Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203
188

For iOS

SystemNavigator.pop(): Does NOT WORK

exit(0): Works but Apple may SUSPEND YOUR APP

Please see:
https://developer.apple.com/library/archive/qa/qa1561/_index.html


For Android

SystemNavigator.pop(): Works and is the RECOMMENDED way of exiting the app.

exit(0): Also works but it's NOT RECOMMENDED as it terminates the Dart VM process immediately and user may think that the app just got crashed.

Please see:
https://api.flutter.dev/flutter/services/SystemNavigator/pop.html

tim-montague
  • 16,217
  • 5
  • 62
  • 51
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
  • 1
    It looks like `SystemNavigator.pop()` is not working under Android emulator. The app is still working in background. So I am not sure if it will be working properly on real device. – BambinoUA Nov 11 '19 at 10:59
  • 2
    @AleksTi It simply exits the app, it doesn't shut the VM process. You may try `exit(0)` for your need. – CopsOnRoad Nov 11 '19 at 11:03
  • `SystemNavigator.pop()` exits my app and shows a message of crash, `exit(0)` works as expected – Jorge Luis Oct 20 '20 at 13:25
  • 1
    Is there a way, which works for both platforms and is recommended as well ? – B.shruti Sep 09 '21 at 12:06
  • 1
    @B.shruti There's no way to make an exit functionality in iOS. For Android, use `SystemNavigator.pop(...)` – CopsOnRoad Sep 09 '21 at 14:53
  • "exit(0): Works but Apple may SUSPEND YOUR APP" - where does Apple state that in the guidelines? Please provide a link for this claim. – tim-montague Dec 28 '21 at 10:15
  • @tim-montague I didn't use the word **"will"**, I said **"may"**, you can read more about it [here](https://developer.apple.com/library/archive/qa/qa1561/_index.html), [here](https://www.ibm.com/support/pages/application-rejected-apple-because-exit-button) and [here](https://stackoverflow.com/questions/7155157/would-a-button-to-exit-my-iphone-app-be-in-violation-of-apples-guidelines) – CopsOnRoad Dec 28 '21 at 13:54
  • @CopsOnRoad - My comment uses the word **"may"** - so, no argument there. Thanks for providing these links, I've edited your answer to include the archived document from Apple, but curious to know if recent Apple Guidelines still take this stance. – tim-montague Dec 29 '21 at 22:11
  • What about Desktop & Web (I think logically exit is incorrect here)? – Banee Ishaque K Jul 08 '22 at 21:22
  • For IOS, you can use with , NullSafety, this package https://pub.dev/packages/flutter_app_minimizer – M E S A B O Jul 23 '22 at 20:46
51

You can do this with SystemNavigator.pop().

Collin Jackson
  • 110,240
  • 31
  • 221
  • 152
  • 1
    Nothing happens on both Android and iOS. Using `exit(0);` does work – Dirk Jul 17 '17 at 10:29
  • 2
    On iOS, `SystemNavigator.pop` is ignored because Apple's human interface guidelines state that applications should not exit themselves. On Android, it should work, and is preferred over calling `dart:io`'s exit method. Consider filing an issue: https://github.com/flutter/flutter/issues/new – Collin Jackson Jul 17 '17 at 13:13
  • Any idea for iOS how can we do in flutter ? – iPatel Mar 06 '19 at 05:22
  • @iPatel You can use exit(0) for iOS, that's it. – CopsOnRoad Mar 07 '19 at 10:53
  • Yo but what about rejection ;( as you told in above comment – iPatel Mar 07 '19 at 11:05
  • You seems like an experienced iOS developer but that question from you surprised me. Actually you should neither let your user nor you should exit the app in iOS (weird). Apple will ban your app if you try to do so. Which is why I love Android :) – CopsOnRoad Mar 07 '19 at 11:49
  • @CopsOnRoad Sorry for silly question I know that apple will reject the App. Actually i'm looking for Flutter but can't find any code for iOS, Above ans working in android perfectly. BTW thanks for your time and suggestion. – iPatel Mar 12 '19 at 10:03
  • @iPatel Don't be sorry, it's no harm to ask question. And yes, don't use exit in your app for iOS part. – CopsOnRoad Mar 12 '19 at 15:16
  • @CopsOnRoad - Where does Apple Human Guidelines state that apps can not exit programmatically? – tim-montague Dec 28 '21 at 10:24
  • @CopsOnRoad - The advice you give @iPatel in these comments, does not reflect the advice you gave me (in your answer, on this question thread). From the links you shared with me, the best I can gather is that ten years ago Apple discouraged the use of `exit`, and encouraged the use of showing the user a dialog so they could close the app if they wanted to do so. However, I do not know if this is Apple's current stance, as I'm unable to find any official mention of that in Apple's iOS guidelines. – tim-montague Dec 29 '21 at 23:30
50

Answers are provided already but please don't just copy paste those into your code base without knowing what you are doing:

If you use SystemChannels.platform.invokeMethod('SystemNavigator.pop'); note that doc is clearly mentioning:

Instructs the system navigator to remove this activity from the stack and return to the previous activity.

On iOS, calls to this method are ignored because Apple's human interface guidelines state that applications should not exit themselves.

You can use exit(0). And that will terminate the Dart VM process immediately with the given exit code. But remember that doc says:

This does not wait for any asynchronous operations to terminate. Using exit is therefore very likely to lose data.

Anyway the doc also did note SystemChannels.platform.invokeMethod('SystemNavigator.pop');:

This method should be preferred over calling dart:io's exit method, as the latter may cause the underlying platform to act as if the application had crashed.

So, keep remember what you are doing.

Blasanka
  • 21,001
  • 12
  • 102
  • 104
  • 20
    You wrote so many clever notes but... what the **correct way** to programmatically exit from app without potential suspension in iOS as described below? – BambinoUA Nov 11 '19 at 10:28
  • Why `SystemChannels.platform.invokeMethod('SystemNavigator.pop')` and not simply `SystemNavigator.pop();`? – Csaba Toth May 28 '21 at 00:38
  • 1
    @CsabaToth both are okay, using `invokeMethod` we are directly calling native android `pop` method. At that time Im writing may be flutter method `pop` did not exist. may be the `SystemNavigator.pop();` invoke native method to exit (Check the method source code, I havent checked it). – Blasanka May 28 '21 at 01:05
24

you can call this by checking platform dependent condition. perform different action on click for android and 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")
)
tim-montague
  • 16,217
  • 5
  • 62
  • 51
Shirsh Shukla
  • 5,491
  • 3
  • 31
  • 44
11

I prefer using

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

Although, exit(0) also works but the app closes abruptly and doesn't look nice, kind of seems that the app has crashed.

 Future.delayed(const Duration(milliseconds: 1000), () {
       exit(0);
      });
10

the only solution I have seen so far, accepted in both stores is:

for android:

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

for ios:

there is no possibility of closing the app BUT you can move it to the background with https://pub.dev/packages/minimize_app like:

MinimizeApp.minimizeApp();

enjoy!

pinkfloyd
  • 255
  • 4
  • 13
3

This worked for me;

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),
      ), 
  );
}
Herman
  • 137
  • 1
  • 4
2

I am calling _getOutOfApp function, this is not package;

    void _getOutOfApp {

      if (Platform.isIOS) {

        try {
          exit(0); 
        } catch (e) {
          SystemNavigator.pop(); // for IOS, not true this, you can make comment this :)
        }

      } else {

        try {
          SystemNavigator.pop(); // sometimes it cant exit app  
        } catch (e) {
          exit(0); // so i am giving crash to app ... sad :(
        }

      }
    }
2

You can use SystemNavigator.pop(); for Android and for iOS use exit(0);

here is example-

if (Platform.isIOS) {
    exit(0);
    } else {
    SystemNavigator.pop();
            }

don't forget import import 'dart:io'; on top

Abir Ahsan
  • 2,649
  • 29
  • 51
2

I created a mixin for the closing like this:

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

mixin AppCloser {
  void closeApp() {
    if (Platform.isAndroid) {
      SystemNavigator.pop();
    } else if (Platform.isIOS) {
      exit(0);
    }
  }
}

Then I just add it on the Page like this:

class _HomePageState extends State<HomePage> with AppCloser {
    ...

    child: ElevatedButton(
        onPressed: () => { closeApp() },
        child: Text('Close'),
    ),

    ...   
}
MeLean
  • 3,092
  • 6
  • 29
  • 43
1

This worked for me. Create a function, and in your onPressed function just call this function. Since exit(0) is not recommended by apple for iOS apps, I opted for this library here: https://pub.dev/packages/minimize_app. Below is the code snippet:

void closeApp(){
   if(Platform.isAndroid){
       SystemChannels.platform.invokeMethod('SystemNavigator.pop');            
   }else{
       MinimizeApp.minimizeApp();
   }
}
ali sampson
  • 321
  • 4
  • 7