Flutter Secure Storage 错误 Null check operator used on a null value
Flutter Secure Storage error Null check operator used on a null value
我正在尝试制作一个包含登录屏幕和主屏幕(目前只有两个屏幕)的 Flutter 应用程序。我也在使用 Flutter Secure Storage 和 Http 库。
每当应用程序启动时,我希望应用程序检查两个道具 accessKey 和 accessId 是否存储在安全存储中。如果找不到 accessId,它会自动生成并分配给 Uuid 库。而 accessKey 不是本地生成的,而是由 API.
提供的
应用导航到:
1). HomeScreen,如果accessKey存储在Secure Storage中并且认证成功。
2). SignInScreen,如果没有找到accessKey或者验证失败。
我的问题是,每次我执行读取操作时,Secure Storage 都会不断抛出错误“Null 检查运算符用于空值”手术。我已经初始化了存储变量,但是这个问题一直出现。
这是我的安全存储 class 代码:
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class FAS {
static FlutterSecureStorage? _storage;
static void init() {
_storage = const FlutterSecureStorage(
aOptions: AndroidOptions(encryptedSharedPreferences: true),
);
}
static Future<String?> read(String key) async {
return _storage!.read(key: key);
}
static Future<Map<String, String>> readAll() async {
return _storage!.readAll();
}
static Future<void> write(String key, String value) async {
await _storage!.write(key: key, value: value);
}
static Future<void> delete(String key) async {
await _storage!.delete(key: key);
}
static Future<void> deleteAll() async {
await _storage!.deleteAll();
}
}
之前,该代码的部分是这样的:
static const FlutterSecureStorage _storage = FlutterSecureStorage(aOptions: AndroidOptions(encryptedSharedPreferences: true));
没有初始化方法。
但我一直收到同样的错误。
这是我的 main.dart:
import 'package:flutter/material.dart';
import 'package:unified_bot_app/pages/home_page.dart';
import 'package:uuid/uuid.dart';
import './models/fas.dart';
import './pages/sign_in_page.dart';
import './request_methods.dart';
Future<void> tryAssignAccessId() async {
String? accessId = await FAS.read("ACCESS_ID");
if (accessId == null) {
await FAS.write("ACCESS_ID", (const Uuid()).v4());
}
}
void main() {
FAS.init();
tryAssignAccessId(); // <- Error
runApp(
MaterialApp(
home: FutureBuilder<bool>(
builder: (ctx, a) {
if (a.connectionState == ConnectionState.done) {
if (a.data!) return HomePage();
return const SignInPage();
}
return const Center(child: CircularProgressIndicator());
},
future: () async {
try {
String? accessKey = await FAS.read("ACCESS_KEY");
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
return false;
}
}(),
),
theme: ThemeData(fontFamily: "Josefin Sans"),
),
);
}
这是我重新启动应用程序时得到的输出:
Restarted application in 531ms. E/flutter (20760):
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Null
check operator used on a null value E/flutter (20760): #0
MethodChannel.binaryMessenger
package:flutter/…/services/platform_channel.dart:121 E/flutter
(20760): #1 MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:146 E/flutter
(20760): #2 MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:329 E/flutter
(20760): #3 MethodChannelFlutterSecureStorage.read
package:flutter_secure_storage_platform_interface/src/method_channel_flutter_secure_storage.dart:49
E/flutter (20760): #4 FlutterSecureStorage.read
package:flutter_secure_storage/flutter_secure_storage.dart:91
E/flutter (20760): #5 FAS.read
package:unified_bot_app/models/fas.dart:13 E/flutter (20760): #6
tryAssignAccessId package:unified_bot_app/main.dart:10 E/flutter
(20760): #7 main package:unified_bot_app/main.dart:18 E/flutter
(20760): #8 _runMainZoned..
(dart:ui/hooks.dart:145:25) E/flutter (20760): #9 _rootRun
(dart:async/zone.dart:1428:13) E/flutter (20760): #10
_CustomZone.run (dart:async/zone.dart:1328:19) E/flutter (20760): #11 _runZoned (dart:async/zone.dart:1863:10) E/flutter (20760): #12 runZonedGuarded (dart:async/zone.dart:1851:12) E/flutter (20760): #13
_runMainZoned. (dart:ui/hooks.dart:141:5) E/flutter (20760): #14 _delayEntrypointInvocation.
(dart:isolate-patch/isolate_patch.dart:283:19) E/flutter (20760): #15
_RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) E/flutter (20760):
D/EGL_emulation(20760): app_time_stats: avg=14143.50ms min=14143.50ms
max=14143.50ms count=1
但是,当我将前两行放在最后(在 runApp(..) 之后)时,错误消失了:
void main() {
runApp(
MaterialApp(
home: FutureBuilder<bool>(
builder: (ctx, a) {
if (a.connectionState == ConnectionState.done) {
if (a.data!) return HomePage();
return const SignInPage();
}
return const Center(child: CircularProgressIndicator());
},
future: () async {
try {
String? accessKey = await FAS.read("ACCESS_KEY"); // <- Error re-appears here
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
return false;
}
}(),
),
theme: ThemeData(fontFamily: "Josefin Sans"),
),
);
FAS.init();
tryAssignAccessId();
}
但是这样做,错误会再次出现在标记的行上。
我很困惑。发生了什么?
感谢任何帮助。
编辑 1:
我尝试在调用第二个 read() 方法之前调用 init() 方法,但抛出相同的错误。
更新部分:
future: () async {
try {
FAS.init();
String? accessKey = await FAS.read("ACCESS_KEY");
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
print(e);
return false;
}
}(),
控制台输出:
Restarted application in 510ms. I/flutter (20760): Null check operator
used on a null value D/EGL_emulation(20760): app_time_stats:
avg=1899.03ms min=1899.03ms max=1899.03ms count=1
我通过添加包含所有方法的新空白页解决了这个问题。
空白页文件:
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import '../models/fas.dart';
import '../request_methods.dart';
import './home_page.dart';
import './sign_in_page.dart';
class BlankPage extends StatelessWidget {
Future<void> _tryAssignAccessId() async {
String? accessId = await FAS.read("ACCESS_ID");
if (accessId == null) {
await FAS.write("ACCESS_ID", (const Uuid()).v4());
}
}
Future<bool> _checkAuth() async {
try {
String? accessKey = await FAS.read("ACCESS_KEY");
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
return false;
}
}
@override
Widget build(BuildContext context) {
FAS.init();
_tryAssignAccessId();
_checkAuth().then((result) {
if (result) {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (ctx) => HomePage()));
} else {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (ctx) => const SignInPage()));
}
});
return Scaffold();
}
}
已更新 main.dart(供参考):
import 'package:flutter/material.dart';
import './pages/blank.dart';
void main() {
runApp(
MaterialApp(
home: BlankPage(),
theme: ThemeData(fontFamily: "Josefin Sans"),
),
);
}
我通过添加
解决了这个问题
WidgetsFlutterBinding.ensureInitialized();
到 runApp() 之前的 main() 方法。
我正在尝试制作一个包含登录屏幕和主屏幕(目前只有两个屏幕)的 Flutter 应用程序。我也在使用 Flutter Secure Storage 和 Http 库。
每当应用程序启动时,我希望应用程序检查两个道具 accessKey 和 accessId 是否存储在安全存储中。如果找不到 accessId,它会自动生成并分配给 Uuid 库。而 accessKey 不是本地生成的,而是由 API.
提供的应用导航到:
1). HomeScreen,如果accessKey存储在Secure Storage中并且认证成功。
2). SignInScreen,如果没有找到accessKey或者验证失败。
我的问题是,每次我执行读取操作时,Secure Storage 都会不断抛出错误“Null 检查运算符用于空值”手术。我已经初始化了存储变量,但是这个问题一直出现。
这是我的安全存储 class 代码:
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class FAS {
static FlutterSecureStorage? _storage;
static void init() {
_storage = const FlutterSecureStorage(
aOptions: AndroidOptions(encryptedSharedPreferences: true),
);
}
static Future<String?> read(String key) async {
return _storage!.read(key: key);
}
static Future<Map<String, String>> readAll() async {
return _storage!.readAll();
}
static Future<void> write(String key, String value) async {
await _storage!.write(key: key, value: value);
}
static Future<void> delete(String key) async {
await _storage!.delete(key: key);
}
static Future<void> deleteAll() async {
await _storage!.deleteAll();
}
}
之前,该代码的部分是这样的:
static const FlutterSecureStorage _storage = FlutterSecureStorage(aOptions: AndroidOptions(encryptedSharedPreferences: true));
没有初始化方法。
但我一直收到同样的错误。
这是我的 main.dart:
import 'package:flutter/material.dart';
import 'package:unified_bot_app/pages/home_page.dart';
import 'package:uuid/uuid.dart';
import './models/fas.dart';
import './pages/sign_in_page.dart';
import './request_methods.dart';
Future<void> tryAssignAccessId() async {
String? accessId = await FAS.read("ACCESS_ID");
if (accessId == null) {
await FAS.write("ACCESS_ID", (const Uuid()).v4());
}
}
void main() {
FAS.init();
tryAssignAccessId(); // <- Error
runApp(
MaterialApp(
home: FutureBuilder<bool>(
builder: (ctx, a) {
if (a.connectionState == ConnectionState.done) {
if (a.data!) return HomePage();
return const SignInPage();
}
return const Center(child: CircularProgressIndicator());
},
future: () async {
try {
String? accessKey = await FAS.read("ACCESS_KEY");
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
return false;
}
}(),
),
theme: ThemeData(fontFamily: "Josefin Sans"),
),
);
}
这是我重新启动应用程序时得到的输出:
Restarted application in 531ms. E/flutter (20760):
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Null
check operator used on a null value E/flutter (20760): #0
MethodChannel.binaryMessenger
package:flutter/…/services/platform_channel.dart:121 E/flutter
(20760): #1 MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:146 E/flutter
(20760): #2 MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:329 E/flutter
(20760): #3 MethodChannelFlutterSecureStorage.read
package:flutter_secure_storage_platform_interface/src/method_channel_flutter_secure_storage.dart:49
E/flutter (20760): #4 FlutterSecureStorage.read
package:flutter_secure_storage/flutter_secure_storage.dart:91
E/flutter (20760): #5 FAS.read
package:unified_bot_app/models/fas.dart:13 E/flutter (20760): #6
tryAssignAccessId package:unified_bot_app/main.dart:10 E/flutter
(20760): #7 main package:unified_bot_app/main.dart:18 E/flutter
(20760): #8 _runMainZoned..
(dart:ui/hooks.dart:145:25) E/flutter (20760): #9 _rootRun
(dart:async/zone.dart:1428:13) E/flutter (20760): #10
_CustomZone.run (dart:async/zone.dart:1328:19) E/flutter (20760): #11 _runZoned (dart:async/zone.dart:1863:10) E/flutter (20760): #12 runZonedGuarded (dart:async/zone.dart:1851:12) E/flutter (20760): #13
_runMainZoned. (dart:ui/hooks.dart:141:5) E/flutter (20760): #14 _delayEntrypointInvocation.
(dart:isolate-patch/isolate_patch.dart:283:19) E/flutter (20760): #15
_RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) E/flutter (20760):
D/EGL_emulation(20760): app_time_stats: avg=14143.50ms min=14143.50ms
max=14143.50ms count=1
但是,当我将前两行放在最后(在 runApp(..) 之后)时,错误消失了:
void main() {
runApp(
MaterialApp(
home: FutureBuilder<bool>(
builder: (ctx, a) {
if (a.connectionState == ConnectionState.done) {
if (a.data!) return HomePage();
return const SignInPage();
}
return const Center(child: CircularProgressIndicator());
},
future: () async {
try {
String? accessKey = await FAS.read("ACCESS_KEY"); // <- Error re-appears here
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
return false;
}
}(),
),
theme: ThemeData(fontFamily: "Josefin Sans"),
),
);
FAS.init();
tryAssignAccessId();
}
但是这样做,错误会再次出现在标记的行上。
我很困惑。发生了什么? 感谢任何帮助。
编辑 1:
我尝试在调用第二个 read() 方法之前调用 init() 方法,但抛出相同的错误。
更新部分:
future: () async {
try {
FAS.init();
String? accessKey = await FAS.read("ACCESS_KEY");
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
print(e);
return false;
}
}(),
控制台输出:
Restarted application in 510ms. I/flutter (20760): Null check operator
used on a null value D/EGL_emulation(20760): app_time_stats:
avg=1899.03ms min=1899.03ms max=1899.03ms count=1
我通过添加包含所有方法的新空白页解决了这个问题。
空白页文件:
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import '../models/fas.dart';
import '../request_methods.dart';
import './home_page.dart';
import './sign_in_page.dart';
class BlankPage extends StatelessWidget {
Future<void> _tryAssignAccessId() async {
String? accessId = await FAS.read("ACCESS_ID");
if (accessId == null) {
await FAS.write("ACCESS_ID", (const Uuid()).v4());
}
}
Future<bool> _checkAuth() async {
try {
String? accessKey = await FAS.read("ACCESS_KEY");
if (accessKey == null) {
return false;
}
return await HTTP.authenticate(accessKey);
} catch (e) {
return false;
}
}
@override
Widget build(BuildContext context) {
FAS.init();
_tryAssignAccessId();
_checkAuth().then((result) {
if (result) {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (ctx) => HomePage()));
} else {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (ctx) => const SignInPage()));
}
});
return Scaffold();
}
}
已更新 main.dart(供参考):
import 'package:flutter/material.dart';
import './pages/blank.dart';
void main() {
runApp(
MaterialApp(
home: BlankPage(),
theme: ThemeData(fontFamily: "Josefin Sans"),
),
);
}
我通过添加
解决了这个问题WidgetsFlutterBinding.ensureInitialized();
到 runApp() 之前的 main() 方法。