处理不完全处理
Dispose doesn't dispose completely
我注意到了一些奇怪的事情,很可能是因为我不理解这个概念。
我正在收听来自 firebase 的云消息。我有 2 个飞镖文件 A 和 B。
A 看起来像:
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
FirebaseMessaging firebaseMessaging = new FirebaseMessaging();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
@override
void initState() {
super.initState();
firebaseMessaging.configure(
onLaunch: (Map<String, dynamic> msg) {
print(" onLaunch called $msg");
},
onResume: (Map<String, dynamic> msg) {
print(" onResume called ${(msg)}");
},
onMessage: (Map<String, dynamic> msg) {
//showNotification(msg);
print(" onMessage called in Activity A ${(msg)}");//--!!!!!-------!!!!->notice this
},
);
firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, alert: true, badge: true));
firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings setting) {
print('IOS Setting Registered');
});
firebaseMessaging.getToken().then((token) {
print("token: "+token);
});
flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
var android = new AndroidInitializationSettings('@mipmap/ic_launcher');
var iOS = new IOSInitializationSettings();
var initSetttings = new InitializationSettings(android, iOS);
flutterLocalNotificationsPlugin.initialize(initSetttings);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>Sample() ));// calling screen B from action of app bar
},
)
],
),
body: new Container(),
);
}
}
如果在 "Activity A" 中调用了一条新消息,请注意我在控制台中打印的行。
现在 B 看起来像:
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class Sample extends StatefulWidget {
@override
_SampleState createState() => _SampleState();
}
class _SampleState extends State<Sample> {
@override
void dispose(){
super.dispose();
}
FirebaseMessaging firebaseMessaging1 = new FirebaseMessaging();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin1;
@override
void initState() {
super.initState();
firebaseMessaging1.configure(
onLaunch: (Map<String, dynamic> msg) {
print(" onLaunch called $msg");
},
onResume: (Map<String, dynamic> msg) {
print(" onResume called ${(msg)}");
},
onMessage: (Map<String, dynamic> msg) {
//showNotification(msg);
print(" onMessage called in Activity B ${(msg)}");//----!!!---!!!!---Notice this
},
);
firebaseMessaging1.requestNotificationPermissions(
const IosNotificationSettings(sound: true, alert: true, badge: true));
firebaseMessaging1.onIosSettingsRegistered
.listen((IosNotificationSettings setting) {
print('IOS Setting Registered');
});
firebaseMessaging1.getToken().then((token) {
print("token: "+token);
});
flutterLocalNotificationsPlugin1 = new FlutterLocalNotificationsPlugin();
var android = new AndroidInitializationSettings('@mipmap/ic_launcher');
var iOS = new IOSInitializationSettings();
var initSetttings = new InitializationSettings(android, iOS);
flutterLocalNotificationsPlugin1.initialize(initSetttings);
print(firebaseMessaging1.toString());
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}
所以目标很简单。当通知到达时,根据我们所在的 activity,它应该执行不同的操作。
如果在A,打印通知到达A
如果在B,打印通知到达B
但问题是,当我从 B 切换回 A(使用 Navigator push 从 A 调用 B)时,它仍然打印 Notification arrived in B
处置没有完全处置或者我遗漏了一些东西
dispose 没有做任何花哨的事情。 你的 工作是处理自定义 dispose 行为。
更具体地说,您必须明确清理可能造成的所有混乱。在您的情况下,这意味着取消订阅 firebase 的流。
这转化为以下内容:
StreamSubscription streamSubscription;
Stream myStream;
@override
void initState() {
super.initState();
streamSubscription = myStream.listen((foo) {
print(foo);
});
}
@override
void dispose() {
super.dispose();
streamSubscription.cancel();
}
您必须对所有收听的流和类似对象(例如 Listenable
)执行相同的操作
我注意到了一些奇怪的事情,很可能是因为我不理解这个概念。
我正在收听来自 firebase 的云消息。我有 2 个飞镖文件 A 和 B。
A 看起来像:
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
FirebaseMessaging firebaseMessaging = new FirebaseMessaging();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
@override
void initState() {
super.initState();
firebaseMessaging.configure(
onLaunch: (Map<String, dynamic> msg) {
print(" onLaunch called $msg");
},
onResume: (Map<String, dynamic> msg) {
print(" onResume called ${(msg)}");
},
onMessage: (Map<String, dynamic> msg) {
//showNotification(msg);
print(" onMessage called in Activity A ${(msg)}");//--!!!!!-------!!!!->notice this
},
);
firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, alert: true, badge: true));
firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings setting) {
print('IOS Setting Registered');
});
firebaseMessaging.getToken().then((token) {
print("token: "+token);
});
flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
var android = new AndroidInitializationSettings('@mipmap/ic_launcher');
var iOS = new IOSInitializationSettings();
var initSetttings = new InitializationSettings(android, iOS);
flutterLocalNotificationsPlugin.initialize(initSetttings);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>Sample() ));// calling screen B from action of app bar
},
)
],
),
body: new Container(),
);
}
}
如果在 "Activity A" 中调用了一条新消息,请注意我在控制台中打印的行。
现在 B 看起来像:
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class Sample extends StatefulWidget {
@override
_SampleState createState() => _SampleState();
}
class _SampleState extends State<Sample> {
@override
void dispose(){
super.dispose();
}
FirebaseMessaging firebaseMessaging1 = new FirebaseMessaging();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin1;
@override
void initState() {
super.initState();
firebaseMessaging1.configure(
onLaunch: (Map<String, dynamic> msg) {
print(" onLaunch called $msg");
},
onResume: (Map<String, dynamic> msg) {
print(" onResume called ${(msg)}");
},
onMessage: (Map<String, dynamic> msg) {
//showNotification(msg);
print(" onMessage called in Activity B ${(msg)}");//----!!!---!!!!---Notice this
},
);
firebaseMessaging1.requestNotificationPermissions(
const IosNotificationSettings(sound: true, alert: true, badge: true));
firebaseMessaging1.onIosSettingsRegistered
.listen((IosNotificationSettings setting) {
print('IOS Setting Registered');
});
firebaseMessaging1.getToken().then((token) {
print("token: "+token);
});
flutterLocalNotificationsPlugin1 = new FlutterLocalNotificationsPlugin();
var android = new AndroidInitializationSettings('@mipmap/ic_launcher');
var iOS = new IOSInitializationSettings();
var initSetttings = new InitializationSettings(android, iOS);
flutterLocalNotificationsPlugin1.initialize(initSetttings);
print(firebaseMessaging1.toString());
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}
所以目标很简单。当通知到达时,根据我们所在的 activity,它应该执行不同的操作。
如果在A,打印通知到达A
如果在B,打印通知到达B
但问题是,当我从 B 切换回 A(使用 Navigator push 从 A 调用 B)时,它仍然打印 Notification arrived in B
处置没有完全处置或者我遗漏了一些东西
dispose 没有做任何花哨的事情。 你的 工作是处理自定义 dispose 行为。
更具体地说,您必须明确清理可能造成的所有混乱。在您的情况下,这意味着取消订阅 firebase 的流。
这转化为以下内容:
StreamSubscription streamSubscription;
Stream myStream;
@override
void initState() {
super.initState();
streamSubscription = myStream.listen((foo) {
print(foo);
});
}
@override
void dispose() {
super.dispose();
streamSubscription.cancel();
}
您必须对所有收听的流和类似对象(例如 Listenable
)执行相同的操作