在运行时出现此错误“用于空值的空检查运算符”
Posted
技术标签:
【中文标题】在运行时出现此错误“用于空值的空检查运算符”【英文标题】:Getting This Error on Run Time "Null check operator used on a null value" 【发布时间】:2021-10-10 16:46:47 【问题描述】:我正在使用 api owlbot 构建一个字典应用程序。我的代码运行罚款没有显示错误。但是在运行时间之后,我收到错误════════小部件捕获的异常══════════════════════════════════ ══════════════ 用于空值的空检查运算符 ══════════════════════════════════════════════════ ══════════════════
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: DictionaryPage(),
);
我的词典页面代码:
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart';
import 'package:flutter/material.dart';
class DictionaryPage extends StatefulWidget
@override
_DictionaryPageState createState() => _DictionaryPageState();
class _DictionaryPageState extends State<DictionaryPage>
String url = "https://owlbot.info/api/v4/dictionary/";
String token = "Your Key";
TextEditingController textEditingController = TextEditingController();
// Stream for loading the text as soon as it is typed
late StreamController streamController;
Stream? _stream;
Timer? _debounce;
// search function
searchText() async
if (textEditingController.text.length == 0)
streamController.add(null);
return;
streamController.add("waiting");
Response response =
await get(url + textEditingController.text.trim() as Uri,
// do provide spacing after Token
headers: "Authorization": "Token " + token);
streamController.add(json.decode(response.body));
@override
void initState()
super.initState();
streamController = StreamController();
_stream = streamController.stream;
@override
Widget build(BuildContext context)
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title: Text(
"Dictionary nw",
style: TextStyle(color: Colors.white),
),
centerTitle: true,
bottom: PreferredSize(
preferredSize: Size.fromHeight(45),
child: Row(
children: [
Expanded(
child: Container(
margin: const EdgeInsets.only(left: 12, bottom: 11.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
color: Colors.white),
child: TextFormField(
onChanged: (String? text)
if (_debounce!.isActive) _debounce?.cancel();
_debounce =
Timer(const Duration(milliseconds: 1000), ()
searchText();
);
,
controller: textEditingController,
decoration: InputDecoration(
hintText: "Search for a word",
contentPadding: const EdgeInsets.only(left: 24.0),
// removing the input border
border: InputBorder.none,
),
),
),
),
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: ()
searchText();
,
)
],
),
),
),
body: Container(
margin: EdgeInsets.all(8),
child: StreamBuilder(
builder: (BuildContext context, AsyncSnapshot snapshot)
if (snapshot.data == null)
return Center(
child: Text("Enter a search word"),
);
if (snapshot.data == "waiting")
return Center(
child: CircularProgressIndicator(),
);
// output
return ListView.builder(
itemCount: snapshot.data["definitions"].length,
itemBuilder: (BuildContext context, int index)
return ListBody(
children: [
Container(
color: Colors.grey[300],
child: ListTile(
leading: snapshot.data["definitions"][index]
["image_url"] ==
null
? null
: CircleAvatar(
backgroundImage: NetworkImage(snapshot
.data["definitions"][index]["image_url"]),
),
title: Text(textEditingController.text.trim() +
"(" +
snapshot.data["definitions"][index]["type"] +
")"),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
snapshot.data["definitions"][index]["definition"]),
)
],
);
,
);
,
stream: _stream,
),
),
),
);
根据我的研究,我认为这个错误发生在 ,
if (_debounce!.isActive) _debounce?.cancel();
_debounce =
Timer(const Duration(milliseconds: 1000), ()
searchText();
);
,
这个,我需要根据这个改变,
Use a local variable
var f = foo;
if (f != null)
var len = f.length; // Safe
Use ?. and ??
var len = foo?.length ?? 0;
【问题讨论】:
【参考方案1】:您需要检查_debounce
是否已经初始化(即它不为空):
onChanged: (String? text)
// Use a local variable, as your snippet hints
final Timer? debounce = _debounce;
// Check if it's initialized AND if it's active
if (debounce != null && debounce.isActive)
debounce.cancel();
// Initialize a new timer
_debounce = Timer(const Duration(milliseconds: 1000), ()
searchText();
);
,
【讨论】:
就这么做:debounce?.cancel();
。如果您在非活动计时器上调用 cancel()
,则不会发生任何事情,因此无需测试它是否处于活动状态:api.dart.dev/stable/2.13.4/dart-async/Timer/cancel.html
在“?.”的情况下运算符,您也可以省略对局部变量的赋值。以上是关于在运行时出现此错误“用于空值的空检查运算符”的主要内容,如果未能解决你的问题,请参考以下文章
如何修复颤振中的“未处理的异常:用于空值的空检查运算符”错误?
如何在颤振发布方法中修复“未处理的异常:用于空值的空检查运算符”