expo: Expo Location. startLocationUpdatesAsync and TaskManager.defineTask, task crash and unregistering

🐛 Bug Report

Environment

Expo CLI 3.2.3 environment info: System: OS: macOS 10.15 Shell: 3.2.57 - /bin/bash Binaries: Node: 12.10.0 - ~/.nvm/versions/node/v12.10.0/bin/node Yarn: 1.17.3 - ~/.yarn/bin/yarn npm: 6.10.3 - ~/.nvm/versions/node/v12.10.0/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman IDEs: Android Studio: 3.1 AI-173.4720617 Xcode: 11.1/11A1027 - /usr/bin/xcodebuild npmPackages: expo: ^35.0.0 => 35.0.0 react: 16.8.3 => 16.8.3 react-native: https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz => 0.59.8 npmGlobalPackages: expo-cli: 3.2.3 “expo-task-manager”: “~7.0.0”, “expo-location”: “~7.0.0”, “expo-permissions”: “~7.0.0”, “expo-constants”: “~7.0.0”

Standalone app, Android.

Steps to Reproduce

Just use the example provided in expo docs regarding background location task. Or the one I provided. Enable the location task, check it has been enabled. Quit app. When the first location change is reported and task is run, it quits and the task is unregistered, and doesn’t get triggered anymore.

Expected Behavior

Background location is reported when app is minimised or quit.

Actual Behavior

When app is quitted and the first location change is reported and task is run, the task is unregistered, and doesn’t get triggered anymore. Also some errors are generated.

Reproducible Demo

https://snack.expo.io/@sorinbogdan/ecba97

Errors from Logcat: `D/Zygote: Forked child process 26327 10-17 17:20:07.514 1255-1287/? I/ActivityManager: Start proc 26327:com.myapp.location/u0a247 for broadcast {com.myapp.location/expo.modules.taskManager.TaskBroadcastReceiver} D/FirebaseApp: com.google.firebase.auth.FirebaseAuth is not linked. Skipping initialization. 10-17 17:20:07.524 26327-26327/? E/myapp.locatio: Not starting debugger since process cannot load the jdwp agent. I/myapp.locatio: The ClassLoaderContext is a special shared library. W/myapp.locatio: Unsupported class loader V/DynamiteModule: Dynamite loader version >= 2, using loadModule2NoCrashUtils W/myapp.locatio: ClassLoaderContext type mismatch. expected=PCL, found=DLC (PCL[] | DLC[];PCL[/data/app/com.myapp.location-z9T0Jp5Hh5WgiKmDZCgpeA==/base.apk4174445279:/data/app/com.myapp.location-z9T0Jp5Hh5WgiKmDZCgpeA==/base.apk!classes2.dex3392624095]{PCL[/system/framework/org.apache.http.legacy.jar*1038351580]}) 10-17 17:20:07.749 26327-26353/? W/myapp.locatio: Found duplicate classes, falling back to extracting from APK : /data/user_de/0/com.google.android.gms/app_chimera/m/00000055/dl-AdsFdrDynamite.integ_20461000000.apk NOTE: This wastes RAM and hurts startup performance. Found duplicated class when checking oat files: ‘Landroid/support/annotation/Keep;’ in /data/user_de/0/com.google.android.gms/app_chimera/m/00000055/dl-AdsFdrDynamite.integ_20461000000.apk and /data/app/com.myapp.location-z9T0Jp5Hh5WgiKmDZCgpeA==/base.apk 10-17 17:20:07.837 26327-26327/? D/SoLoader: init start

adb shell setprop debug.firebase.analytics.app com.myapp.location 10-17 17:20:07.944 26327-26378/? E/Fabric: Fabric could not be initialized, API key missing from AndroidManifest.xml. Add the following tag to your Application element <meta-data android:name="io.fabric.ApiKey" android:value="YOUR_API_KEY"/> D/b: Loaded exp.host status page. Failed to retrieve settings from https://settings.crashlytics.com/spi/v2/platforms/android/apps/com.myapp.location/settings E/Answers: Failed to retrieve settings

I/TaskService: Registered task with name ‘background-location-task’ for app with ID ‘@synkedup/location’. I/TaskService: Handling intent with task name ‘background-location-task’ and appId ‘@synkedup/location’. I/TaskService: Handling job with task name ‘background-location-task’ for app with ID ‘@synkedup/location’. E/Expo: Cannot initialize app loader. host.exp.exponent.e.a.<init> [class android.content.Context] E/TaskService: Cannot execute background task because application loader can’t be found. I/TaskService: Unregistering task ‘background-location-task’ for app ‘@synkedup/location’. I/myapp.locatio: Waiting for a blocking GC ProfileSaver I/myapp.locatio: WaitForGcToComplete blocked ProfileSaver on ClassLinker for 6.886ms …28 minutes later… I/ActivityManager: Killing 26327:com.myapp.location/u0a247 (adj 985): empty #17 ` (cc @tsapeta )

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 6
  • Comments: 21 (12 by maintainers)

Most upvoted comments

np @ribeiroevandro … BTW I’ve updated the sample code to reproduce the issue with the latest SDK 36 at https://github.com/jeromecornet/expo-android-backgroundfetch

Is some find the solution for this ? or any workaround to fix this problem. Please, anyone, take the in charge to fix this issue

Thanks @superyarik. Does the crash happen after the task gets unregistered or before ?

I had a few minutes to take a look at the source code, and it would make sense to me if it was after, because of a race condition between LocationTaskConsumer#didUnregister() https://github.com/expo/expo/blob/db1369230ddf17b020d46367bec30905547a22a5/android/versioned-abis/expoview-abi35_0_0/src/main/java/abi35_0_0/expo/modules/location/taskConsumers/LocationTaskConsumer.java#L79-L82 and the onComplete() listener https://github.com/expo/expo/blob/db1369230ddf17b020d46367bec30905547a22a5/android/versioned-abis/expoview-abi35_0_0/src/main/java/abi35_0_0/expo/modules/location/taskConsumers/LocationTaskConsumer.java#L117-L124 which ends up calling maybeReportDeferredLocations() which calls shouldReportDeferredLocations() which in turn calls getOptions() on a null mTask: https://github.com/expo/expo/blob/db1369230ddf17b020d46367bec30905547a22a5/android/versioned-abis/expoview-abi35_0_0/src/main/java/abi35_0_0/expo/modules/location/taskConsumers/LocationTaskConsumer.java#L305-L316

@tsapeta maybe the fix for the crash in https://github.com/expo/expo/issues/6290#issuecomment-554881030 is simply to add a guard early in in shouldReportDeferredLocations() https://github.com/expo/expo/blob/db1369230ddf17b020d46367bec30905547a22a5/android/versioned-abis/expoview-abi35_0_0/src/main/java/abi35_0_0/expo/modules/location/taskConsumers/LocationTaskConsumer.java#L305-L313 to return if the task has already been unregistered ?

But that said it would not fix the underlying issue (in TaskManager) which is that the task gets unregistered in the first place due to a loader error (Cannot execute background task because application loader can't be found.)

The same is happening here. Sometimes works in debug mode with android 9 emulator or a real device via usb, but never work fine when build apk, install and open the app. Another android emulator versions have same bugs in bg geolocation too, like 6.0, 7.11 and 8.1.