颤动:如何强制重启应用程序(在生产模式下)?

时间:2018-05-01 10:58:47

标签: flutter

生产模式中,有没有办法强制完全重启应用程序(我谈论开发时的热重载!)。

实际使用案例:

  • 在初始化过程中,应用程序检测到没有网络连接。缺乏网络连接可能阻止了正确的启动(例如加载外部资源,如JSON文件......)。

  • 在最初的握手过程中,需要下载一些重要资源的新版本(更新类型)。

在这两种用例中,我希望应用程序继续完全重启,而不是必须在ApplicationState级别构建复杂的逻辑。

非常感谢您的提示。

7 个答案:

答案 0 :(得分:28)

您可以将整个应用程序包装到statefulwidget中。当您想要重新启动应用程序时,请使用具有不同Key的子项重建该statefulwidget。

这会让你失去你应用的整个状态。

import 'package:flutter/material.dart';

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

class RestartWidget extends StatefulWidget {
  final Widget child;

  RestartWidget({this.child});

  static restartApp(BuildContext context) {
    final _RestartWidgetState state =
        context.ancestorStateOfType(const TypeMatcher<_RestartWidgetState>());
    state.restartApp();
  }

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

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

  void restartApp() {
    this.setState(() {
      key = new UniqueKey();
    });
  }

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

在此示例中,您可以使用RestartWidget.restartApp(context)从任何位置重置您的应用。

答案 1 :(得分:18)

flutter_phoenix package基于Rémi Rousselet's answer,使其更加简单。

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

然后,当您需要重新启动应用程序时,只需致电:

Phoenix.rebirth(context);

答案 2 :(得分:3)

如此简单package:flutter_restart

dependencies:
flutter_restart: ^0.0.3

使用:

void _restartApp() async {
  FlutterRestart.restartApp();
}

答案 3 :(得分:2)

您还可以使用runApp(new MyWidget)函数执行类似的操作

这就是这个功能的作用:

给给定小部件充气并将其附加到屏幕上。

小部件在布局期间被赋予约束,迫使它填充整个屏幕。如果您希望将窗口小部件对齐到屏幕的一侧(例如,顶部),请考虑使用“对齐”窗口小部件。如果您希望将窗口小部件居中,也可以使用“中心”窗口小部件

再次调用runApp将从屏幕上分离先前的根小部件,并将给定的小部件附加到其位置。将新窗口小部件树与先前窗口小部件树进行比较,并将任何差异应用于基础渲染树,类似于StatefulWidget在调用State.setState后重建时所发生的情况。

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

答案 4 :(得分:2)

我开发了 restart_app 插件来原生重启整个应用。


更新:

对于任何获得此例外的人:

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

只需停止并重新构建应用即可。

答案 5 :(得分:2)

我发现 Hossein's restart_app 包对于原生重启也非常有用(不仅在 Flutter 级别)。

对于遇到 MissingPluginException 错误的每个人,只需在设备上重新安装应用程序,这意味着热重载将不起作用。该应用程序具有需要在 Android/iOS 应用程序中编译的本地方法。

答案 6 :(得分:0)

我想要一种简单的方法来更改应用程序的主题(浅色,深色),因此我通过使用SharedPreferences包来做到这一点。这是我的主要功能:

void main() async {
    WidgetsFlutterBinding.ensureInitialized();
    final prefs = await SharedPreferences.getInstance();

    runApp(MyApp(prefs: prefs));
}

然后我只需在应用程序的任何位置调用此方法即可处理更改:

runApp(MyApp(prefs: prefs));