对空值使用的空检查运算符

我是 Flutter的新手

我得到了这个错误,当我运行我的简单颤振应用程序。我不能找出为什么会发生这个错误。

错误

Null check operator used on a null value

我的代码在 main.dart

import 'package:flutter/material.dart';
import './ui/login.dart';


void main() {
  

runApp(new MaterialApp(
title: "Login Template",
home: new Login(),
));
}


我在 login.dart 中的代码

import 'package:flutter/material.dart';


class Login extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new LoginState();
}
}


class LoginState extends State<Login> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Login"),
centerTitle: true,
backgroundColor: Colors.blueAccent.shade50,
),
backgroundColor: Colors.blueGrey,
body: new Container(


),
);
}
}


代码的错误跟踪

Running Gradle task 'assembleDebug'...
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...
Waiting for SM J710F to report its views...
D/vndksupport(29495): Loading /vendor/lib/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace.
Debug service listening on ws://127.0.0.1:39899/9RorUiKtUb4=/ws
Syncing files to device SM J710F...
D/ViewRootImpl@4ac1ef4[MainActivity](29495): MSG_RESIZED_REPORT: frame=Rect(0, 0 - 720, 1280) ci=Rect(0, 48 - 0, 582) vi=Rect(0, 48 - 0, 582) or=1
D/ViewRootImpl@4ac1ef4[MainActivity](29495): MSG_WINDOW_FOCUS_CHANGED 1
V/InputMethodManager(29495): Starting input: tba=android.view.inputmethod.EditorInfo@3049fea nm : com.sivaram.login_template ic=null
D/InputMethodManager(29495): startInputInner - Id : 0
I/InputMethodManager(29495): startInputInner - mService.startInputOrWindowGainedFocus
D/InputTransport(29495): Input channel constructed: fd=96
V/InputMethodManager(29495): Starting input: tba=android.view.inputmethod.EditorInfo@aad92db nm : com.sivaram.login_template ic=null
D/InputMethodManager(29495): startInputInner - Id : 0
D/ViewRootImpl@4ac1ef4[MainActivity](29495): MSG_RESIZED: frame=Rect(0, 0 - 720, 1280) ci=Rect(0, 48 - 0, 0) vi=Rect(0, 48 - 0, 0) or=1
D/ViewRootImpl@4ac1ef4[MainActivity](29495): Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=true 3791374336} changed=false
D/libGLESv2(29495): STS_GLApi : DTS, ODTC are not allowed for Package : com.sivaram.login_template


════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
Null check operator used on a null value
Login file:///home/kadavul/IdeaProjects/login_template/lib/main.dart:8:15
════════════════════════════════════════════════════════════════════════════════════════════════════
V/InputMethodManager(29495): Starting input: tba=android.view.inputmethod.EditorInfo@a0ff0af nm : com.sivaram.login_template ic=null
D/InputMethodManager(29495): startInputInner - Id : 0
I/InputMethodManager(29495): startInputInner - mService.startInputOrWindowGainedFocus
D/InputTransport(29495): Input channel constructed: fd=87
D/InputTransport(29495): Input channel destroyed: fd=96
D/SurfaceView(29495): windowStopped(true) false 77b9092 of ViewRootImpl@4ac1ef4[MainActivity]
D/SurfaceView(29495): BG show() Surface(name=Background for - SurfaceView - com.sivaram.login_template/com.sivaram.login_template.MainActivity@77b9092@0) io.flutter.embedding.android.FlutterSurfaceView{77b9092 V.E...... ........ 0,0-720,1280}
D/SurfaceView(29495): surfaceDestroyed 1 #1 io.flutter.embedding.android.FlutterSurfaceView{77b9092 V.E...... ........ 0,0-720,1280}
V/InputMethodManager(29495): Starting input: tba=android.view.inputmethod.EditorInfo@a78fcbc nm : com.sivaram.login_template ic=null
D/InputMethodManager(29495): startInputInner - Id : 0
I/InputMethodManager(29495): startInputInner - mService.startInputOrWindowGainedFocus
D/InputTransport(29495): Input channel constructed: fd=91
D/InputTransport(29495): Input channel destroyed: fd=87
D/SurfaceView(29495): windowStopped(false) true 77b9092 of ViewRootImpl@4ac1ef4[MainActivity]
D/SurfaceView(29495): BG show() Surface(name=Background for - SurfaceView - com.sivaram.login_template/com.sivaram.login_template.MainActivity@77b9092@1) io.flutter.embedding.android.FlutterSurfaceView{77b9092 V.E...... ........ 0,0-720,1280}
V/Surface (29495): sf_framedrop debug : 0x4f4c, game : false, logging : 0
D/SurfaceView(29495): surfaceCreated 1 #1 io.flutter.embedding.android.FlutterSurfaceView{77b9092 V.E...... ........ 0,0-720,1280}
D/mali_winsys(29495): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000,  [720x1280]-format:1
D/SurfaceView(29495): surfaceChanged (720,1280) 1 #1 io.flutter.embedding.android.FlutterSurfaceView{77b9092 V.E...... ........ 0,0-720,1280}
D/SurfaceView(29495): BG destroy() Surface(name=Background for - SurfaceView - com.sivaram.login_template/com.sivaram.login_template.MainActivity@77b9092@0) io.flutter.embedding.android.FlutterSurfaceView{77b9092 V.E...... ........ 0,0-720,1280}
D/ViewRootImpl@4ac1ef4[MainActivity](29495): Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x3 surface={valid=true 3791374336} changed=false
D/ViewRootImpl@4ac1ef4[MainActivity](29495): MSG_RESIZED_REPORT: frame=Rect(0, 0 - 720, 1280) ci=Rect(0, 48 - 0, 0) vi=Rect(0, 48 - 0, 0) or=1
V/InputMethodManager(29495): Starting input: tba=android.view.inputmethod.EditorInfo@7ed1445 nm : com.sivaram.login_template ic=null
D/InputMethodManager(29495): startInputInner - Id : 0
I/InputMethodManager(29495): startInputInner - mService.startInputOrWindowGainedFocus
D/InputTransport(29495): Input channel constructed: fd=92
D/InputTransport(29495): Input channel destroyed: fd=91
D/SurfaceView(29495): windowStopped(true) false 77b9092 of ViewRootImpl@4ac1ef4[MainActivity]
D/SurfaceView(29495): BG show() Surface(name=Background for - SurfaceView - com.sivaram.login_template/com.sivaram.login_template.MainActivity@77b9092@1) io.flutter.embedding.android.FlutterSurfaceView{77b9092 V.E...... ........ 0,0-720,1280}
D/SurfaceView(29495): surfaceDestroyed 1 #1 io.flutter.embedding.android.FlutterSurfaceView{77b9092 V.E...... ........ 0,0-720,1280}


我的颤振医生输出


fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Doctor summary (to see all details, run flutter doctor -v):
Failed to find the latest git commit date: VersionCheckError: Command exited with code 128: git -c log.showSignature=false log -n 1 --pretty=format:%ad --date=iso
Standard out:
Standard error: fatal: your current branch 'master' does not have any commits yet


Returning 1970-01-01 05:30:00.000 instead.
[✓] Flutter (Channel unknown, 0.0.0-unknown, on Linux, locale en_US.UTF-8)
 

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Android Studio (version 4.0)
[!] VS Code (version 1.50.0)
✗ Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (1 available)


! Doctor found issues in 1 category.

有人能解决这个问题吗?

328656 次浏览

这个问题可能与 Dartlang中集成的 null 安全性有关。现在你可以切换频道,使用稳定的频道:

flutter channel stable
flutter upgrade

倾向于 科普森路的答案,如果不起作用只降级。

我们需要按照以下步骤解决上述问题


- flutter channel stable
- flutter upgrade
- flutter pub cache repair //To perform a clean reinstall of the packages in your system cache, use pub cache repair
- flutter clean //flutter clean will delete the /build folder

当我尝试 flutter channel stable 的时候。我得到了另一个错误,因为我有两个 flutters,一个来自 Snapd,另一个来自 git 克隆方法。

然后,我用 git 克隆来配置 SDK。最后,我使用 Git 克隆的 SDK flutter 执行以下所有命令

flutter channel stable
- ~/flutter/bin/flutter upgrade
- ~/flutter/bin/flutter pub cache repair //To perform a clean reinstall of the packages in your system cache, use pub cache repair
- ~/flutter/bin/flutter clean //flutter clean will delete the /build folder


对于像我这样的新手,尝试重新启动应用程序,而不是热重新加载它。

任何正在使用 明白了软件包并有类似问题的人,这里有一个最简单的解决方案。 只需在主函数的顶部添加 保证初始化() ;

改变你的主要功能如下:

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await di.init()
runApp(MyApp());}

不要降低扑动的等级

问题:

如果对未初始化的可空实例使用 bang 操作符(!) ,则会发生此错误。

例如:

String? string; // Nullable String


void main() {
var len = string!.length; // Runtime error: Null check operator used on a null value
}

解决方案:

打开日志,必须有一行指向项目中发生错误的文件:

对空值使用的空检查运算符

# 0 main (package: example/main.dart: 22:16)

一旦你到了那里,你可以使用以下任何一种方法来修复它:

  • 使用局部变量

    var s = string;
    if (s != null) {
    var len = s.length; // Safe
    }
    
  • 使用 ?.和? ?

    var len = string?.length ?? 0; // Provide a default value if string was null.
    

堆栈跟踪还可以指向不属于您的项目的文件,例如:

1. 使用 NavigatorMediaQuery的人士

尝试异步访问 BuildContext时也会发生此错误。

因此,在访问 BuildContext之前,应该首先检查小部件是否为 mounted

Future<void> foo() async {
// Some async operation
await compute();


// Check `mounted` before accessing 'context'.
if (mounted) {
MediaQuery.of(context).size;
Navigator.of(context).pop();
}
}

2. 使用 Color的人士

你在吸毒

Colors.blueAccent.shade50

如果你查看源代码,你会发现:

Color get shade50 => this[50]!; // <-- This bang operator is causing the error.

为了解决这个错误,你应该使用一些其他颜色,不是 null,也许是 100的阴影。

Colors.blueAccent[100]
// or
Colors.blue.shade100

3. 使用 FutureBuilder/StreamBuilder的人士:

你可以用两种方法来解决这个问题:

  • FutureBuilder/StreamBuilder指定一个类型

    FutureBuilder<List<int>>( // <-- type 'List<int>' is specified.
    future: _listOfInt(),
    builder: (_, snapshot) {
    if (snapshot.hasData) {
    List<int> myList = snapshot.data!; // <-- Your data
    }
    return Container();
    },
    )
    
  • 使用 as向下播放 Object到您的类型,比如 ListMap

    FutureBuilder(
    future: _listOfInt(),
    builder: (_, snapshot) {
    if (snapshot.hasData) {
    var myList = snapshot.data! as List<int>; // <-- Your data using 'as'
    }
    return Container();
    },
    )
    

Provider反模式

如果我们在包之外得到这个错误,那么我们可能需要研究如何使用第三方依赖关系。在我的例子中,Provider反模式引起了问题。

Provider对象的生命周期不同于常规小部件,因为它可以是 意外地重新创建或根本没有创建,这取决于使用情况。

例子一

create:块之外初始化 ChangeNotifierProvider时,我遇到了一个简单的可重复示例。

很好

ChangeNotifierProvider(
create: (_) => ToDoContainerModel(),
builder: (context, _) {
return home;
}));

很糟糕

ChangeNotifierProvider(
create: (_) => model,
builder: (context, _) {
return home;
}));

这在 储存库中被记录为一种反模式:

不要使用缺省构造函数重用现有的 ChangeNotifier。

例子2

另一个可能导致类似副作用的反模式是:

如果要创建对象,请不要使用 .value构造函数,否则可能会产生不希望的副作用。

很好

ChangeNotifierProvider.value(
create: (_) => MyModel(),
child: ...
)

很糟糕

ChangeNotifierProvider.value(
value: MyModel(),
child: ...
)

错误的原因

为了保持一致性,sqflite数据库应该只有一次对 openDatabase的调用。通过使用 ChangeNotifierProvider反模式,我得到了这个错误,因为我不止一次触发了 openDatabase。因此,我触发了未处理的异常,因为当我们在重复调用中指定相同的 db 路径时,sqflite在内部为 openDatabase返回 null。

提示: 当您在包之外得到此错误时,请检查第三方文档。

当您使用已经完成的上下文时,也会发生此问题。例如,Navigator.pop(context),因此您可以再次检查代码序列。

在我这边,我用 late代替 ?来修复它

前情提要: UserRepository? userRepository;

将其替换为: late UserRepository userRepository;

出现了同样的问题,这个错误是云火恢复规则的结果。我设定了 request.time的规则,而 timestamp.date已经过期了。所以您可以检查它并设置规则 allow read, write: if true;allow read, write: if request.auth != null;

如果您试图使用可空值设置文本,那么您可以添加这一行来解决这个问题。

如果名称的值为空,并且必须指定可为空的值,则添加

name ?? ""

你得到这个错误,因为你没有初始化你的 GetxController。请在应用程序启动时初始化所有其他控制器的位置初始化您的控制器。

像这样初始化

  • Get.put(YourController()) 马上
  • Get.lazyPut(()=> YourController()) 当你需要的时候