flutter-geolocator
flutter-geolocator copied to clipboard
[Android] MainActivity has leaked IntentReceiver
🐛 Bug Report
It reports MainActivity has leaked IntentReceiver com.baseflow.geolocator.location.LocationServiceStatusReceiver, when exiting the app.
Expected behavior
Call unregisterReceiver() when exiting the app.
Reproduction steps
- Checkout the example project
- Build the example project
- Run the example app
- Give location permission by tapping the button
- Exit the app
Error log in the console:
E/ActivityThread(17969): Activity com.baseflow.geolocator_example.MainActivity has leaked IntentReceiver com.baseflow.geolocator.location.LocationServiceStatusReceiver@10738ec that was originally registered here. Are you missing a call to unregisterReceiver()?
E/ActivityThread(17969): android.app.IntentReceiverLeaked: Activity com.baseflow.geolocator_example.MainActivity has leaked IntentReceiver com.baseflow.geolocator.location.LocationServiceStatusReceiver@10738ec that was originally registered here. Are you missing a call to unregisterReceiver()?
E/ActivityThread(17969): at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:1717)
E/ActivityThread(17969): at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:1494)
E/ActivityThread(17969): at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1757)
E/ActivityThread(17969): at android.app.ContextImpl.registerReceiver(ContextImpl.java:1723)
E/ActivityThread(17969): at android.app.ContextImpl.registerReceiver(ContextImpl.java:1711)
E/ActivityThread(17969): at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:724)
E/ActivityThread(17969): at com.baseflow.geolocator.LocationServiceHandlerImpl.onListen(LocationServiceHandlerImpl.java:57)
E/ActivityThread(17969): at io.flutter.plugin.common.EventChannel$IncomingStreamRequestHandler.onListen(EventChannel.java:218)
E/ActivityThread(17969): at io.flutter.plugin.common.EventChannel$IncomingStreamRequestHandler.onMessage(EventChannel.java:197)
E/ActivityThread(17969): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:178)
E/ActivityThread(17969): at io.flutter.embedding.engine.dart.DartMessenger.lambda$handleMessageFromDart$0$DartMessenger(DartMessenger.java:206)
E/ActivityThread(17969): at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$6ZD1MYkhaLxyPjtoFDxe45u43DI.run(Unknown Source:12)
E/ActivityThread(17969): at android.os.Handler.handleCallback(Handler.java:938)
E/ActivityThread(17969): at android.os.Handler.dispatchMessage(Handler.java:99)
E/ActivityThread(17969): at android.os.Looper.loopOnce(Looper.java:201)
E/ActivityThread(17969): at android.os.Looper.loop(Looper.java:288)
E/ActivityThread(17969): at android.app.ActivityThread.main(ActivityThread.java:7839)
E/ActivityThread(17969): at java.lang.reflect.Method.invoke(Native Method)
E/ActivityThread(17969): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/ActivityThread(17969): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Application finished.
Configuration
Version: 8.0.0
Platform:
- [ ] :iphone: iOS
- [x] :robot: Android
Thanks for reporting your issue @hahastudio. I can't manage to reproduce your issue. Can you please provide me your flutter doctor -v and which device you're using?
I have an idea why this error occurs. In the stopListening method in the LocationServiceHandlerImpl class, the Receiver is never unregistered, when the app suddenly stops (The stopListening method is called when the application is de-attached from the FlutterEngine). The Receiver is only getting unregistered when manually cancelling the LocationServiceStatusStream in your code. When this issue is affecting the performance of your app, you can try forking the geolocator repo and changing the stopListening method yourself from:
void stopListening(){
if(channel == null){
return;
}
channel.setStreamHandler(null);
channel = null;
}
To:
void stopListening(){
if(channel == null){
return;
}
if(activity != null){
activity.unregisterReceiver(this.receiver);
}
channel.setStreamHandler(null);
channel = null;
}
Another solution would be to cancel the LocationServiceStatusStream in f.e. your main.dart when the app is closed. You can realise this by making use of the Flutter Lifecycle events, such as onDestroy.
I'm not sure if this will do the trick, but you can always try. I can't discuss your issue with the main author of the geolocator plugin, since the holidays are coming. Let me know if this fixes your issue!
@florissmit1 thx for your reply!
Here is the output of flutter doctor -v:
[✓] Flutter (Channel stable, 2.8.1, on macOS 12.0.1 21A559 darwin-x64, locale zh-Hans-CN)
• Flutter version 2.8.1 at /Users/hahastudio/Projects/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 77d935af4d (7 天前), 2021-12-16 08:37:33 -0800
• Engine revision 890a5fca2e
• Dart version 2.15.1
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0-rc1)
• Android SDK at /Users/hahastudio/Library/Android/sdk
• Platform android-31, build-tools 32.0.0-rc1
• ANDROID_HOME = /Users/hahastudio/Library/Android/sdk
• ANDROID_SDK_ROOT = /Users/hahastudio/Library/Android/sdk
• Java binary at: /Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment AdoptOpenJDK (build 13.0.2+8)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 13.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• CocoaPods version 1.10.0
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2020.3)
• Android Studio at /Applications/Android Studio.app/Contents
• 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.10+0-b96-7281165)
[✓] VS Code (version 1.63.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.29.0
[✓] Connected device (3 available)
• sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64 • Android 12 (API 31) (emulator)
• macOS (desktop) • macos • darwin-x64 • macOS 12.0.1 21A559 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 96.0.4664.110
• No issues found!
I tried to modify LocationServiceHandlerImpl in geo_android like you said, and it can resolve the issue.
But about canceling the LocationServiceStatusStream, I tried to dispose _serviceStatusStreamSubscription like _positionStreamSubscription in the example project, but it still throw the same exception.