flutter_workmanager
flutter_workmanager copied to clipboard
🐞When use 'await' to Obtain shared preferences, I got "Worker result FAILURE for Work".
- [x] I have read the README
- [x] I have done the setup for Android
- [x] I have done the setup for iOS
- [x] I have ran the sample app and it does not work there
Version
| Technology | Version |
|---|---|
| Workmanager version | 0.4.1 |
| SharedPreferences version | 2.0.13 |
Describe the error
I get the fail I/WM-WorkerWrapper(25984): Worker result FAILURE for Work [ id=eaf19926-15cd-4ba9-8858-ab8ed99182aa, tags={ be.tramckrijte.workmanager.BackgroundWorker } ] when I try to run the Debugging tips sample code in the README.md.
Then I mark final prefs = await SharedPreferences.getInstance(); and try and catch, it get worker result successful.
May I ask same suggestion? Thanks.
My main full code as below:
onst myTask = "syncWithTheBackEnd";
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async{
switch (task) {
case myTask:
int? totalExecutions;
final prefs = await SharedPreferences.getInstance(); //Initialize dependency
try { //add code execution
totalExecutions = await prefs.getInt("totalExecutions");
// prefs.setInt("totalExecutions",
// totalExecutions == null ? 1 : totalExecutions + 1);
}
catch (err) {
Logger().e(err.toString()); // Logger flutter package, prints error on the debug console
throw Exception(err);
}
break;
case Workmanager.iOSBackgroundTask:
print("iOS background fetch delegate ran");
break;
}
return Future.value(true);
});
}
void main() {
// add this, and it should be the first line in main method
WidgetsFlutterBinding.ensureInitialized();
//Workmanager.initialize(callbackDispatcher);
Workmanager().initialize(callbackDispatcher, isInDebugMode: false);
Workmanager().registerOneOffTask(
"1",
myTask, //This is the value that will be returned in the #callbackDispatcher
);
runApp(MyApp());
}
//----------------------------------------------------------------------------------------------------
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('HKT 線上教室'),
),
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with WidgetsBindingObserver{
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print('$state');
}
@override
void initState() {
super.initState();
print('initState+++');
WidgetsBinding.instance!.addObserver(this);
}
@override
void dispose() {
print('dispose+++');
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
child: Text('跳到 B 頁'),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => BPage()));
},
),
);
}
}
class BPage extends StatefulWidget {
@override
_BPageState createState() => _BPageState();
}
class _BPageState extends State<BPage> with WidgetsBindingObserver {
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print('$state');
// if (state == AppLifecycleState.resumed) {
// print('resumed');
// }
// else if (state == AppLifecycleState.inactive) {
// print('inactive');
// }
// else if (state == AppLifecycleState.paused) {
// print('paused');
// }
}
@override
void initState() {
super.initState();
print('initState+++');
WidgetsBinding.instance!.addObserver(this);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('didChangeDependencies+++');
}
@override
void deactivate() {
print('deactivate+++');
super.deactivate();
}
@override
void dispose() {
print('dispose+++');
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('我是 B 頁'),
),
body: Center(
child: RaisedButton(
child: Text('返回首頁'),
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
}
Output of debug
Launching lib\main.dart on Android SDK built for x86 in debug mode...
Running Gradle task 'assembleDebug'...
√ Built build\app\outputs\flutter-apk\app-debug.apk.
Installing build\app\outputs\flutter-apk\app.apk...
Debug service listening on ws://127.0.0.1:52084/zak3O5cjSnk=/ws
Syncing files to device Android SDK built for x86...
D/EGL_emulation(25984): eglCreateContext: 0xf1820a00: maj 2 min 0 rcv 2
D/EGL_emulation(25984): eglCreateContext: 0xf18211e0: maj 2 min 0 rcv 2
D/HostConnection(25984): HostConnection::get() New Host Connection established 0xf1828f70, tid 26038
D/HostConnection(25984): HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2
D/EGL_emulation(25984): eglMakeCurrent: 0xf18211e0: ver 2 0 (tinfo 0xf1b5ec10) (first time)
I/flutter (25984): initState+++
I/WM-WorkerWrapper(25984): Worker result FAILURE for Work [ id=eaf19926-15cd-4ba9-8858-ab8ed99182aa, tags={ be.tramckrijte.workmanager.BackgroundWorker } ]
Output of flutter doctor -v
[√] Flutter (Channel stable, 2.10.1, on Microsoft Windows [Version 10.0.19043.1466], locale zh-TW)
• Flutter version 2.10.1 at C:\flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision db747aa133 (6 days ago), 2022-02-09 13:57:35 -0600
• Engine revision ab46186b24
• Dart version 2.16.1
• DevTools version 2.9.2
[√] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
• Android SDK at C:\Users\USER\AppData\Local\Android\sdk
• Platform android-32, build-tools 32.0.0
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)
• All Android licenses accepted.
[√] Chrome - develop for the web
• Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.0.5)
• Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
• Visual Studio Community 2022 version 17.0.32112.339
• Windows 10 SDK version 10.0.19041.0
[√] Android Studio (version 2021.1)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)
[√] Connected device (4 available)
• Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.19043.1466]
• Chrome (web) • chrome • web-javascript • Google Chrome 98.0.4758.82
• Edge (web) • edge • web-javascript • Microsoft Edge 98.0.1108.43
[√] HTTP Host Availability
• All required HTTP hosts are available
• No issues found!
Check if below workaround from https://github.com/flutter/flutter/issues/98473#issuecomment-1041895729 fixes the issue
Thanks for filing this; I've filed #98591 for the general problem (which we weren't aware of when updating the plugins).
While we investigate whether we can adjust Flutter to handle this automatically in the future, here's a workaround that should allow using the current versions of the plugins:
- Add dependencies on
shared_preferences_androidandshared_preferences_ios.- At the beginning of your background isolate entry point, add something like:
if (Platform.isAndroid) SharedPreferencesAndroid.registerWith(); if (Platform.isIOS) SharedPreferencesIOS.registerWith();
@absar i didn't get the solution yet! please explain it
@mohammedsalem97 something like this.
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async{
if (Platform.isAndroid) SharedPreferencesAndroid.registerWith(); // here
if (Platform.isIOS) SharedPreferencesIOS.registerWith(); // and here
switch (task) {
case myTask:
int? totalExecutions;
final prefs = await SharedPreferences.getInstance(); //Initialize dependency
try { //add code execution
totalExecutions = await prefs.getInt("totalExecutions");
// prefs.setInt("totalExecutions",
// totalExecutions == null ? 1 : totalExecutions + 1);
}
catch (err) {
Logger().e(err.toString()); // Logger flutter package, prints error on the debug console
throw Exception(err);
}
break;
case Workmanager.iOSBackgroundTask:
print("iOS background fetch delegate ran");
break;
}
return Future.value(true);
});
}
The callback above runs in a different Isolate, while some plugins initialization is straight forward as when used in the main Isolate, some might require extra steps to work properly. You should use DartPluginRegistrant.ensureInitialized(); // Initialize dependency When working with plugin in an isolate as well to be on a safer side.