我使用工作经理包启动后台任务,并与主隔离进行通信。
在main.dart中,我的代码如下:
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
// call Workmanager().initialize()
await BackgroundService().init();
// init ReceivePort
var port = ReceivePort();
if (IsolateNameServer.lookupPortByName('bChannel') != null)
IsolateNameServer.removePortNameMapping('bChannel');
IsolateNameServer.registerPortWithName(port.sendPort, 'bChannel');
port.listen((dynamic data) async {
print('[Main][bChannel listener] got $data');
// send http request and update ui
});
BackgroundService().registerPeriodicTask();
print('[Main] init');
runApp(MyApp());
}在background_service.dart中,我的代码如下:
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
try {
switch (task) {
case 'a':
print("[Background] Task A triggered.");
var sendPort = IsolateNameServer.lookupPortByName('bChannel');
if (sendPort != null) {
sendPort.send('message from background');
print("[Background] message sent.");
} else {
print("[Background] no send port.");
// send http request in background and save result to SharedPreferences
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('result', 'result_message');
}
print("[Background] Task A finished.");
break;
}
return Future.value(true);
} catch (e) {
print("[Background] $e");
return Future.value(false);
}
});
}
class BackgroundService {
// singleton things
static final BackgroundService _instance = BackgroundService._internal();
factory BackgroundService() {
return _instance;
}
BackgroundService._internal() ;
void registerWeatherRefreshPeriodicTask() {
Workmanager().registerPeriodicTask(
'TaskA',
'TaskA',
initialDelay: Duration(minutes: 1),
frequency: Duration(minutes: 15),
constraints: Constraints(
networkType: NetworkType.connected
)
);
}
Future init() async {
Workmanager().initialize(
callbackDispatcher,
isInDebugMode: true,
);
}
}当应用程序在前面和后台运行时,它可以工作。但是,如果该应用程序退出(回击)到Android上,我会看到类似的日志
I/flutter ( 8342): [Main] init
D/FlutterLocationService( 8342): Unbinding from location service.
D/FlutterLocationService( 8342): Destroying service.
I/flutter ( 8342): [Background] Task A triggered.
I/flutter ( 8342): [Background] no send port.
I/flutter ( 8342): [Background] Task A finished.没有日志可以指示主隔离程序使用消息。来自ReceivePort文档
ReceivePort是一种非广播流.这意味着它会缓冲传入的消息,直到注册侦听器为止。
当我再次打开这个应用程序时,它会再次显示[Main] init。因此,我想主要的隔离已经退出,并且没有侦听器到端口。
我想做的是:
我怎样才能实现这一点呢?
发布于 2021-11-28 04:56:25
我放弃了触发主隔离来呈现,而不是后台隔离更新和保存结果,并让主隔离重新呈现,如果它正在运行,否则在初始化期间呈现。
在main.dart中
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
// call Workmanager().initialize()
await BackgroundService().init();
// init ReceivePort
var port = ReceivePort();
if (IsolateNameServer.lookupPortByName('bChannel') != null)
IsolateNameServer.removePortNameMapping('bChannel');
IsolateNameServer.registerPortWithName(port.sendPort, 'bChannel');
port.listen((dynamic data) async {
print('[Main][bChannel listener] got $data');
// refresh shared preferences and trigger render
final prefs = await SharedPreferences.getInstance();
await prefs.reload(); // reload otherwise it will use out-dated data
// add BLoC event
bloc.add(refreshEvent());
});
BackgroundService().registerPeriodicTask();
print('[Main] init');
runApp(MyApp());
}在background_service.dart中
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
try {
// also init and reload shared preferences
// if main isolate contains other initialization works, it should also put here
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.reload();
var httpClient = http.Client();
switch (task) {
case 'a':
print("[Background] Task A triggered.");
// send http request and save the result
var response = await httpClient.get(uri);
await prefs.setString('result', response.body);
var sendPort = IsolateNameServer.lookupPortByName('bChannel');
if (sendPort != null) {
sendPort.send('message from background');
print("[Background] message sent.");
}
print("[Background] Task A finished.");
break;
}
return Future.value(true);
} catch (e) {
print("[Background] $e");
return Future.value(false);
}
});
}https://stackoverflow.com/questions/69976389
复制相似问题