颤动/飞镖静态变量丢失/不断重新初始化

Liv*_*ve0 14 android ios dart flutter

我正在尝试Flutter/Dart的事情.但是当从另一个类访问时,我的静态变量不断重新初始化.

我有一个类,在其单独的dart源文件中,保存服务器状态,声明如下:

class ServerStatus{
  static int newestBinary;
  static bool serverUp;
}
Run Code Online (Sandbox Code Playgroud)

我把它们初始化为@ main()by

ServerStatus.newestBinary = 20;
ServerStatus.serverUp = true;
Run Code Online (Sandbox Code Playgroud)

.之后,当我尝试在我的应用程序中的另一个页面上访问它们时,变量' newestBinary'和' serverUp'都变成了null,就好像它们被重新启动一样.(如果我宣布他们喜欢static int newestBinary = 10;,然后重新分配ServerStatus.newestBinary = 20;main(),它仍然会显示为10,在我的应用程序的另一页.

我的应用程序没有在两个操作之间退出或停止.在什么情况下,静态变量会被重新激活?

如果我必须为应用程序保存全局和常用信息,那么除了使用静态变量之外,最好的方法是什么呢?

提前致谢.

Liv*_*ve0 17

我玩弄了一个小时,意识到这似乎是什么原因.显然我在做的时候:

import 'package:flutter_test_app/main.dart';
Run Code Online (Sandbox Code Playgroud)

它不同于

import 'main.dart';
Run Code Online (Sandbox Code Playgroud)

即使两个源文件都属于同一个包.

所以最后我的测试代码如下:

main.dart:

import 'package:flutter/material.dart';
import 'pageA.dart';
import 'pageB.dart';
import 'pageH.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {

  static bool testFlag = false;
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {

    testFlag = true;
    ThemeData mainTheme = new ThemeData(
      primarySwatch: Colors.cyan,
    );
    print("testFlag @ MyApp: " + testFlag.toString());
    MaterialApp mainApp = new MaterialApp(
      title: 'Instabazaar',
      theme: mainTheme,
      home: new HomePage(title: 'Instabazaar'),
    );

    return mainApp;
  }
}

class HomePage extends StatefulWidget {

  final String title;
  HomePage({Key key, this.title}) : super(key: key);

  @override
  _HomePageState createState() {

    return new _HomePageState();
  }
}

class _HomePageState extends State<HomePage> {
  int _currentPageID = 0; // 0=home, 1=pageA, 2=pageB



  @override
  Widget build(BuildContext context) {

    print("testFlag @ HomePage: " + MyApp.testFlag.toString());


    AppBar appBar = new AppBar(
        title: new Text("TestApp"),
        centerTitle: true,
    );

    BottomNavigationBar bottomNavigationBar = new BottomNavigationBar(
        type: BottomNavigationBarType.shifting,
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text('Home'), backgroundColor: Theme.of(context).accentColor),
          new BottomNavigationBarItem(icon: new Icon(Icons.explore), title: new Text('PageA'), backgroundColor: Colors.purple),
          new BottomNavigationBarItem(icon: new Icon(Icons.star), title: new Text('PageB'), backgroundColor: Colors.redAccent),
        ],
        onTap: (i) => setState( () => _currentPageID = i ),
        currentIndex: _currentPageID
    );


    Scaffold mainScaffold = new Scaffold(
      appBar: appBar,
      body: _getNewSubPage(),
      bottomNavigationBar: bottomNavigationBar,
    );
    return mainScaffold;
  }


  //MARK: navigation


  Widget _getNewSubPage(){
    switch (_currentPageID)
    {
      case 1:
        return new pageA();
      case 2:
        return new pageB();
      default:
        return new pageH();
    }
  }


}
Run Code Online (Sandbox Code Playgroud)

pageA.dart/pageB.dart:

import 'package:flutter/material.dart';
import 'package:flutter_test_app/main.dart';

class pageA extends StatefulWidget{
  pageAState createState() => new pageAState();
}


class pageAState extends State<pageA> {

  @override
  Widget build(BuildContext context) {
    print("testFlag @ pageA: " + MyApp.testFlag.toString());
    return new Container();
  }
}
Run Code Online (Sandbox Code Playgroud)

pageH.dart:

import 'package:flutter/material.dart';
import 'main.dart';

class pageH extends StatefulWidget{
  pageHState createState() => new pageHState();
}


class pageHState extends State<pageH> {
  @override
  Widget build(BuildContext context) {
    print("testFlag @ pageH: " + MyApp.testFlag.toString());
    return new Container();
  }
}
Run Code Online (Sandbox Code Playgroud)

唯一的区别是import语句.但是,对于pageA/pageB,print语句将给出"false".至于pageH,print语句将给出"true".我已经切换了import语句并检查出来.我不熟悉dart实际上如何解释代码,所以我不确定它是一个飞镖的东西,一个设置的东西或一个颤动的东西.我会继续调查,但现在我的问题已经解决了.

谢谢大家的帮助.


Joh*_*vdH 12

class Glob {
  //One instance, needs factory 
  static Glob _instance;
  factory Glob() => _instance ??= new Glob._();
  Glob._();
  //

  String account ='johanacct1';

  String getServerUrl(){
    return 'http://192.168.1.60';
  }

  String getAccountUrl(){
    return getServerUrl()+'/accounts/'+account;
  }
}
Run Code Online (Sandbox Code Playgroud)

在另一个文件中使用它:

`

Glob().getAccountUrl(); //http://192.168.1.60/accounts/johanacct1
Glob().account = 'philip.k.dick';
Glob().getAccountUrl(); //http://192.168.1.60/accounts/philip.k.dick
Run Code Online (Sandbox Code Playgroud)

`import 'glob.dart';当两个文件都在 lib/ 目录中时,它可以工作。(IDK如果其他场景有问题。)


Sto*_*eev 10

如果导入以:"package:your_app_package/file.dart"开头,Flutter和Dart似乎有问题为静态(全局)变量找到相同的实例.

因此,假设您希望在main.dart文件中拥有静态变量(myStaticVariable),您可以在其中拥有MyApp类.并且假设您希望通过使用MyApp.myStaticVariable调用项目中某个不同的.dart文件中的静态变量.

在这种情况下,如果您使用"import package:your_app_package/main.dart"导入main.dart,该变量将具有"null"值,即使它之前已经初始化!

如果你导入main.dart只有"import main.dart"(如果文件在同一目录中)或"import ../main.dart"(如果你的文件是一个目录dipper,那么main.dart),你将为MyApp.myStaticVariable获取正确的值.

我不知道为什么会这样,但也许像@Kevin Moore提到的那样,有一个问题,Flutter团队需要解决它.


Gün*_*uer 7

入口点文件 ( lib/main.dart) 不得包含相对导入,这是一个已知问题。

如果所有导入都以

import 'dart:...';
import 'package:my_project/...'
Run Code Online (Sandbox Code Playgroud)

那么这个问题就可以避免了。

这是因为扑不完全遵循其中的入口点的文件是在酒吧包约定外lib/(如bin/web/tool/test/,或example/)。

另见https://github.com/flutter/flutter/issues/15748

更新 2018-10-17

此问题已在 Dart 中修复,但可能尚未在所有 Flutter 频道中解决。


Rém*_*let 5

您可以直接在声明中初始化静态变量。这样的事情会更好:

class ServerStatus{
  static int newestBinary = 20;
  static bool serverUp = false;
}
Run Code Online (Sandbox Code Playgroud)

另外,您确定您的分配已正确执行吗?如果没有更多的代码,很难给出完整的答案。

另一个原因可能与您如何完成任务有关。你是在做newestBinary = 20;还是ServerStatus.newestBinary = 20;?静态变量不同于全局变量。如果你这样做,newestBinary = 20;你不会改变 ServerStatus 的静态变量,而是一个局部变量。