我有一个应用程序,它使用包含一些数据的本地通知。在本例中,它是从JSON文件中读取的一些引用。
我想做的是每分钟阅读另一个报价,并在主屏幕上更新它。
void main() {
runApp(ChangeNotifierProvider<QuotesRepository>(
create: (context) => QuotesRepository.instance(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
),
));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
var quote = Provider.of<QuotesRepository>(context);
quote.showScheduledNotification();
return Scaffold(
appBar: new AppBar(
backgroundColor: Colors.red,
title: new Text('Flutter notification demo'),
),
body: new Center(
child: Text(
quote.lastMessage.toString(),
style: GoogleFonts.clickerScript(fontSize: 40.0),
),
),
);
}
}
这里是定义提供者的地方:
class QuotesRepository with ChangeNotifier {
String? lastMessage;
QuotesRepository.instance();
Future<void> loadJson(int index) async {
String data = await rootBundle.loadString('assets/quotes.json');
Map<String, dynamic> userMap = jsonDecode(data);
this.lastMessage = userMap['quotes'][index]['quote'];
}
Future<void> showScheduledNotification() async {
int randomValue = 42;
await loadJson(randomValue).then((value) => showNotificationBody());
notifyListeners();
}
Future<void> showNotificationBody() async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
print("Function called");
const androidPlatformChannelSpecifics = AndroidNotificationDetails(
'channel id',
'channel name',
'channel description',
icon: 'flutter_devs',
largeIcon: DrawableResourceAndroidBitmap('flutter_devs'),
);
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
const NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
);
flutterLocalNotificationsPlugin.periodicallyShow(0, '365<3',
this.lastMessage, RepeatInterval.everyMinute, platformChannelSpecifics,
payload: this.lastMessage);
}
}
然而,这每秒钟都会调用该函数,并导致应用程序崩溃。我知道这是因为我调用quote.showScheduledNotification();
,notifyListeners()
将导致它进入无限循环。
但是如何防止这种情况呢?如何只加载一次,然后在每次通知到达时更新lastMessage
。
为了简单起见,我每次都给出相同的引文(42)。
1条答案
按热度按时间qmelpv7a1#
看起来你正在寻找一个init函数。如果你把
MyApp
转换成一个有状态的小部件,你将能够使用stateful
小部件的init方法。这应该可以解决问题的一部分。你几乎不应该在build
函数中使用init函数,因为它会被频繁地调用。PS:关于如何提高应用性能的更多提示,我在my blog上写了一篇文章。