我尝试在宠物项目中使用依赖注入(get_it)和块(flutter_bloc)。但我遇到了下面所示的问题。
I/flutter (23661): Error while creating WeatherInfoLocalDataSource
I/flutter (23661): Error while creating WeatherInfoRepository
I/flutter (23661): Error while creating GetWeatherInfoByCityName
I/flutter (23661): Error while creating WeatherInfoBloc
════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building _BodyBuilder:
You tried to access an instance of SharedPreferences that is not ready yet
'package:get_it/get_it_impl.dart':
package:get_it/get_it_impl.dart:1
Failed assertion: line 404 pos 9: 'instanceFactory.isReady'
The relevant error-causing widget was
Scaffold
lib\…\pages\weather_info_page.dart:25
When the exception was thrown, this was the stack
════════ Exception caught by rendering library ═════════════════════════════════
Each child must be laid out exactly once.
The relevant error-causing widget was
Scaffold
我看了github,stackoverflow上的文章,也看了教程中的代码,但是不明白我做错了什么。有人能解释一下我做错了什么吗?代码:注射容器
final sl = GetIt.instance;
void init() {
//! Features - Weather Check
// Bloc
sl.registerFactory(() => WeatherInfoBloc(
concrete: sl(),
random: sl(),
inputConverter: sl(),
));
// UseCases
sl.registerLazySingleton(() => GetWeatherInfoByCityName(sl()));
sl.registerLazySingleton(() => GetWeatherByRandomCity(sl()));
// Repository
sl.registerLazySingleton<WeatherInfoRepository>(
() => WeatherInfoRepositoryImpl(
localDataSource: sl(),
remoteDataSource: sl(),
networkInfo: sl(),
));
// Data
sl.registerLazySingleton<WeatherInfoRemoteDataSource>(
() => WeatherInfoRemoteDataSourceImpl(httpClient: sl()));
sl.registerLazySingleton<WeatherInfoLocalDataSource>(
() => WeatherInfoLocalDataSourceImpl(sharedPreferences: sl()));
//! Core
sl.registerLazySingleton(() => InputConverter());
sl.registerLazySingleton<NetworkInfo>(() => NetworkInfoImpl(sl()));
//! External
sl.registerSingletonAsync<SharedPreferences>(
() => SharedPreferences.getInstance());
sl.registerLazySingleton(() => http.Client);
sl.registerLazySingleton(() => InternetConnectionChecker());
}
主要的
void main() async {
WidgetsFlutterBinding.ensureInitialized();
di.init();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: true,
theme: ThemeData(primaryColor: Colors.lightBlue.shade800),
home: BlocProvider<WeatherInfoBloc>(
create: (_) => di.sl<WeatherInfoBloc>(),
child: const WeatherInfoPage(),
),
);
}
}
天气信息页面
class WeatherInfoPage extends StatefulWidget {
const WeatherInfoPage({Key? key}) : super(key: key);
@override
State<WeatherInfoPage> createState() => _WeatherInfoPageState();
}
class _WeatherInfoPageState extends State<WeatherInfoPage> {
//late final WeatherInfoBloc _weatherInfoBloc;
// @override
// void initState() {
// super.initState();
// //_weatherInfoBloc = sl<WeatherInfoBloc>();
// //_weatherInfoBloc.add(const WeatherInfoEvent.loadArticles());
// }
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Weather info'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(8),
child: _buildBody(context),
)),
);
}
Widget _buildBody(BuildContext context) {
return Column(
children: <Widget>[
BlocBuilder<WeatherInfoBloc, WeatherInfoState>(
builder: (context, state) {
if (state is Empty) {
return const MessageDisplay(
message: 'Start searching!',
);
} else if (state is Loading) {
return const LoadingWidget();
} else if (state is Loaded) {
return WeatherDisplay(weatherInfo: state.weatherInfo);
} else if (state is Error) {
return MessageDisplay(
message: state.message,
);
}
return const SizedBox.shrink();
},
),
// SizedBox(
// height: MediaQuery.of(context).size.height / 3,
// child: const Placeholder(),
// ),
const SizedBox(
height: 30,
child: SizedBox.shrink(),
),
const WeatherControls(),
],
);
}
Widget _buildBloc(BuildContext context) {
return BlocBuilder<WeatherInfoBloc, WeatherInfoState>(
builder: (context, state) {
if (state is Empty) {
return const MessageDisplay(
message: 'Start searching!',
);
} else if (state is Loading) {
return const LoadingWidget();
} else if (state is Loaded) {
return WeatherDisplay(weatherInfo: state.weatherInfo);
} else if (state is Error) {
return MessageDisplay(
message: state.message,
);
}
return const SizedBox.shrink();
},
);
}
}
如有必要,我将用其他文件补充代码。
UPD:通过添加await di.sl.allReady()解决;int n = int n();在注入过程中,容器忘记给http.Client添加括号,也忘记在与bloc关联的方法中添加await。
2条答案
按热度按时间bvjveswy1#
这是因为共享首选项的使用者是在共享首选项的提供者之前首先创建的,您需要在使用依赖项之前首先提供它,因此您需要将它移动到顶部的某个位置,以便在使用实际的依赖项之前首先创建它
oogrdqng2#
查看此评论:https://stackoverflow.com/a/76115955/8888756