用于空值的空检查运算符
Null check operator used on a null value
我是Flutter
的新手
我在 运行 我的 simple flutter APP 时遇到了这个错误。我无法弄清楚为什么会出现此错误。
错误
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}
我的 flutter 医生输出
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.
任何人都可以为此提供解决方案吗?
该问题可能与 dartlang 中集成的空安全性有关。现在您可以切换频道并使用稳定频道:
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
。我得到了另一个错误,因为我有两个颤振,一个来自 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
对于像我这样的新手,请尝试重新启动应用程序而不是热重载它。
任何正在使用 get_it 软件包并遇到类似问题的人,这里是最简单的解决方案。
只需在 main 函数的顶部添加 WidgetsFlutterBinding.ensureInitialized();。
像这样更改您的主要功能:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await di.init()
runApp(MyApp());}
不要降级 Flutter
问题:
当您在未初始化的可空实例上使用 bang 运算符 (!
) 时会发生此错误。
例如:
String? foo; // Nullable String
void main() {
var len = foo!.length; // Runtime error: Null check operator used on a null value
}
解决方案:
您需要找出您在代码中的什么地方使用了 bang 运算符。到达那里后,您可以使用以下任何解决方案:
使用局部变量
var f = foo;
if (f != null) {
var len = f.length; // Safe
}
使用?.
和??
var len = foo?.length ?? 0; // Provide a default value if foo was null.
回答你的问题:
您正在使用
Colors.blueAccent.shade50
没有第 50
个阴影。如果查看源代码,您会发现:
Color get shade50 => this[50]!; // <-- This bang operator is causing the error.
要解决此错误,您应该使用 null
以外的其他颜色,也许是第 100
个颜色。
Colors.blueAccent[100]
// or
Colors.blue.shade100
对于正在使用 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
向下转换为您的类型,例如 List
或 Map
。
FutureBuilder(
future: _listOfInt(),
builder: (_, snapshot) {
if (snapshot.hasData) {
var myList = snapshot.data! as List<int>; // <-- Your data using 'as'
}
return Container();
},
)
Provider
反模式
如果我们在包外遇到这个错误,那么我们可能需要查看我们是如何使用第三方依赖项的。就我而言,Provider
反模式导致了问题。
Provider
对象的生命周期不同于常规小部件,因为它可以 取决于用途。
示例 1
我在 create:
块之外初始化 ChangeNotifierProvider
时遇到了一个简单的可重现示例。
好
ChangeNotifierProvider(
create: (_) => ToDoContainerModel(),
builder: (context, _) {
return home;
}));
不好
ChangeNotifierProvider(
create: (_) => model,
builder: (context, _) {
return home;
}));
这在 the repository 中记录为反模式:
DON'T reuse an existing ChangeNotifier using the default constructor.
示例 2
另一个可能导致类似副作用的反模式是:
Do not use the .value
constructor if you want to create an object, or you may otherwise have undesired side effects.
好
ChangeNotifierProvider.value(
create: (_) => MyModel(),
child: ...
)
不好
ChangeNotifierProvider.value(
value: MyModel(),
child: ...
)
错误原因
sqflite
数据库应该只调用一次 openDatabase
以保持一致性。使用 ChangeNotifierProvider
反模式,我得到了这个错误,因为我不止一次触发了 openDatabase
。因此,我触发了未处理的异常,因为当我们在重复调用中指定相同的数据库路径时,sqflite
在内部 returns 为 openDatabase
为空。
TIP: Check third-party documentation when you get this error outside of your package.
当您使用已经完成的上下文时,也会出现此问题。例如,Navigator.pop(context)
,所以您可以再次检查您的代码序列。
在我这边,我使用 late
而不是 ?
来修复它
之前:
UserRepository? userRepository;
替换为:late UserRepository userRepository;
我是Flutter
我在 运行 我的 simple flutter APP 时遇到了这个错误。我无法弄清楚为什么会出现此错误。
错误
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}
我的 flutter 医生输出
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.
任何人都可以为此提供解决方案吗?
该问题可能与 dartlang 中集成的空安全性有关。现在您可以切换频道并使用稳定频道:
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
。我得到了另一个错误,因为我有两个颤振,一个来自 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
对于像我这样的新手,请尝试重新启动应用程序而不是热重载它。
任何正在使用 get_it 软件包并遇到类似问题的人,这里是最简单的解决方案。 只需在 main 函数的顶部添加 WidgetsFlutterBinding.ensureInitialized();。
像这样更改您的主要功能:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await di.init()
runApp(MyApp());}
不要降级 Flutter
问题:
当您在未初始化的可空实例上使用 bang 运算符 (!
) 时会发生此错误。
例如:
String? foo; // Nullable String
void main() {
var len = foo!.length; // Runtime error: Null check operator used on a null value
}
解决方案:
您需要找出您在代码中的什么地方使用了 bang 运算符。到达那里后,您可以使用以下任何解决方案:
使用局部变量
var f = foo; if (f != null) { var len = f.length; // Safe }
使用
?.
和??var len = foo?.length ?? 0; // Provide a default value if foo was null.
回答你的问题:
您正在使用
Colors.blueAccent.shade50
没有第 50
个阴影。如果查看源代码,您会发现:
Color get shade50 => this[50]!; // <-- This bang operator is causing the error.
要解决此错误,您应该使用 null
以外的其他颜色,也许是第 100
个颜色。
Colors.blueAccent[100]
// or
Colors.blue.shade100
对于正在使用 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
向下转换为您的类型,例如List
或Map
。FutureBuilder( future: _listOfInt(), builder: (_, snapshot) { if (snapshot.hasData) { var myList = snapshot.data! as List<int>; // <-- Your data using 'as' } return Container(); }, )
Provider
反模式
如果我们在包外遇到这个错误,那么我们可能需要查看我们是如何使用第三方依赖项的。就我而言,Provider
反模式导致了问题。
Provider
对象的生命周期不同于常规小部件,因为它可以
示例 1
我在 create:
块之外初始化 ChangeNotifierProvider
时遇到了一个简单的可重现示例。
好
ChangeNotifierProvider(
create: (_) => ToDoContainerModel(),
builder: (context, _) {
return home;
}));
不好
ChangeNotifierProvider(
create: (_) => model,
builder: (context, _) {
return home;
}));
这在 the repository 中记录为反模式:
DON'T reuse an existing ChangeNotifier using the default constructor.
示例 2
另一个可能导致类似副作用的反模式是:
Do not use the
.value
constructor if you want to create an object, or you may otherwise have undesired side effects.
好
ChangeNotifierProvider.value(
create: (_) => MyModel(),
child: ...
)
不好
ChangeNotifierProvider.value(
value: MyModel(),
child: ...
)
错误原因
sqflite
数据库应该只调用一次 openDatabase
以保持一致性。使用 ChangeNotifierProvider
反模式,我得到了这个错误,因为我不止一次触发了 openDatabase
。因此,我触发了未处理的异常,因为当我们在重复调用中指定相同的数据库路径时,sqflite
在内部 returns 为 openDatabase
为空。
TIP: Check third-party documentation when you get this error outside of your package.
当您使用已经完成的上下文时,也会出现此问题。例如,Navigator.pop(context)
,所以您可以再次检查您的代码序列。
在我这边,我使用 late
而不是 ?
之前:
UserRepository? userRepository;
替换为:late UserRepository userRepository;