Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: how to force an application restart (in production mode)?

Tags:

flutter

In production mode, is there a way to force a full restart of the application (I am not talking about a hot reload at development time!).

Practical use cases:

  • At initialization process the application detects that there is no network connection. The lack of network connectivity might have prevented a correct start up (e.g. loading of external resource such as JSON files...).

  • During the initial handshaking, new versions of some important resources need to be downloaded (kind of update).

In both use cases, I would like the application to proceed with a full restart, rather than having to build a complex logic at the ApplicationState level.

like image 510
boeledi Avatar asked May 01 '18 10:05

boeledi


People also ask

How do you force hot reload in flutter?

Alternatively, you can click the hot button. Enter 'r' in the window while running the application at the command line with the flutter run. See the message in the console after completing the hot reload process successfully.


9 Answers

You could wrap your whole app into a statefulwidget. And when you want to restart you app, rebuild that statefulwidget with a child that possess a different Key.

This would make you loose the whole state of your app.

import 'package:flutter/material.dart';

void main() {
  runApp(
    RestartWidget(
      child: MaterialApp(),
    ),
  );
}

class RestartWidget extends StatefulWidget {
  RestartWidget({this.child});

  final Widget child;

  static void restartApp(BuildContext context) {
    context.findAncestorStateOfType<_RestartWidgetState>().restartApp();
  }

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

class _RestartWidgetState extends State<RestartWidget> {
  Key key = UniqueKey();

  void restartApp() {
    setState(() {
      key = UniqueKey();
    });
  }

  @override
  Widget build(BuildContext context) {
    return KeyedSubtree(
      key: key,
      child: widget.child,
    );
  }
}

In this example you can reset your app from everywhere using RestartWidget.restartApp(context).

like image 160
Rémi Rousselet Avatar answered Oct 04 '22 03:10

Rémi Rousselet


The flutter_phoenix package is based on Rémi Rousselet's answer, making it even simpler.

void main() {
  runApp(
    Phoenix(
      child: App(),
    ),
  );
}

Then when you need to restart the app, just call:

Phoenix.rebirth(context);
like image 33
Tony Avatar answered Oct 04 '22 04:10

Tony


I developed the restart_app plugin to restart the whole app natively.


Update:

For anyone who get this exception:

MissingPluginException(No implementation found for method restartApp on channel restart)

Just stop and rebuild the app.

like image 38
Hossein Yousefpour Avatar answered Oct 04 '22 02:10

Hossein Yousefpour


So simple package: flutter_restart

dependencies:
flutter_restart: ^0.0.3

to use:

void _restartApp() async {
  FlutterRestart.restartApp();
}
like image 32
Mina Farid Avatar answered Oct 04 '22 02:10

Mina Farid


You can also use the runApp(new MyWidget) function to do something similar

This is what this function does:

Inflate the given widget and attach it to the screen.

The widget is given constraints during layout that force it to fill the entire screen. If you wish to align your widget to one side of the screen (e.g., the top), consider using the Align widget. If you wish to center your widget, you can also use the Center widget

Calling runApp again will detach the previous root widget from the screen and attach the given widget in its place. The new widget tree is compared against the previous widget tree and any differences are applied to the underlying render tree, similar to what happens when a StatefulWidget rebuilds after calling State.setState.

https://docs.flutter.io/flutter/widgets/runApp.html

like image 29
David H Moreno Avatar answered Oct 04 '22 04:10

David H Moreno


I just want to add Regarding I have Tried @Remi answer which works great on most of the cases to restart the app. The only problem with the answer is that some things if you are doing Navigation route extensively you probably go to a state which It gives you an error like, The method 'restartApp' was called on null. To resolve this error you have to know the Context and use Navigator.of(context).pop(); multiples times back. For me, the solution is that just go to the initial route. It will inject all the states from a new. Where you want to restart just add this Line.

 Navigator.pushNamedAndRemoveUntil(context,'/',(_) => false);

If you want to only restart a specific widget then the Remi solution is awesome. Thanks for the solution Remi though. It help me understand states in flutter.

like image 29
Shahryar Rafique Avatar answered Oct 04 '22 03:10

Shahryar Rafique


I have found Hossein's restart_app package also pretty useful for native restarts (not only on Flutter level).

To everyone having the MissingPluginException error, just reinstall the app again on the device, means that hot reload won't work. The app has native methods which need to compiled in the Android/iOS App.

like image 26
Flawn Avatar answered Oct 04 '22 04:10

Flawn


I wanted to restart my app after logout. so I used https://pub.dev/packages/flutter_phoenix (flutter phoenix). It worked for me.

  1. Install flutter_phoenix by running this command on your terminal inside your flutter app directory. $ flutter pub add flutter_phoenix
  2. Import it inside your "main.dart".
  3. Wrap your root widget inside Phoenix.
     runApp(
    Phoenix(
      child: MyApp()
  ));

  1. Now you can call this wherever you want to restart your app :- Phoenix.rebirth(context)

Note: flutter_phoenix does not restart the app on OS level, it only restarts the app on app level.

like image 42
Aayush Rawat Avatar answered Oct 04 '22 03:10

Aayush Rawat


Follow the steps-

  1. Go to your terminal and type in the following:
flutter pub add flutter_restart

This will update some dependencies in pubspec.yaml file.

  1. Import the following package in whichever file you want to implement the restart code-
import 'package:flutter_restart/flutter_restart.dart';
  1. Create a void function
void _restartApp() async {
  await FlutterRestart.restartApp();
}
  1. Write this wherever you want to start the app-
_restartApp();
like image 41
lightlessdays Avatar answered Sep 21 '22 06:09

lightlessdays