Leakcanary: Storage permission on Android M

Created on 16 Sep 2015  路  9Comments  路  Source: square/leakcanary

Sometimes the Toast with the message "Dumping memory, app will freeze. Brrr." appears on my application and does not disappear.
I also get a few ANR while this message is visible (I think this is expected) and always select wait instead of killing the application.
The only way to remove the Toast is killing the application.
To install the leakcanary I only added the install method on the application class (LeakCanary.install(this);). It is necessary to do something more?

On my device (OnePlus One with Android 5.1.1) I never get this behaviour but on Android emulator with Android 6.0 it happens with some frequency.

help wanted bug

Most helpful comment

Our workaround has been to add the following to our debug/AndroidManifest.xml:

<!-- Leak canary needs access to External storage to save heap dumps -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

and this to our release/AndroidManifest.xml:

<!-- On KitKat & later, these permissions are no longer required if using getExternalCacheDir
         However there is a bug that the permission is still required on API 21/22 (Lollipop &
         Lollipop_MR1): https://code.google.com/p/android/issues/detail?id=81357
         Therefore maxSdkVersion needs to be set to 22 instead of 19 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="22"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="22"/>

This should mean you only see the Permission > Storage appear on debug builds on Marshmallow. If your release build doesn't need the storage permissions at all, then you can omit the release/AndroidManifest.xml entries

You'll still need to request the runtime permission when you launch the debug version of your app.

Perhaps LeakCanary could store it's heap dumps in the app's external cache directory instead of Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS); ? That would mean you couldn't easily copy the heap dumps off the device using adb though.

All 9 comments

+1
on M - Preview 3 on Real Device Nexus 5

This happens on M preview if Storage permission is not enabled. So as a temporary workaround, can go to settings and enable Storage.
Not sure what the permanent fix should be, but glad to help out with a PR if any suggestions from maintainers.

Was confused why we were using the storage permission, this makes perfect sense now! Our workaround is to request the permission using Google's new permission handling for our debug version.

Can the permission be removed from the releaseCompile version though? The storage permission still comes through even for release builds, which might seem strange to users.

Our workaround has been to add the following to our debug/AndroidManifest.xml:

<!-- Leak canary needs access to External storage to save heap dumps -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

and this to our release/AndroidManifest.xml:

<!-- On KitKat & later, these permissions are no longer required if using getExternalCacheDir
         However there is a bug that the permission is still required on API 21/22 (Lollipop &
         Lollipop_MR1): https://code.google.com/p/android/issues/detail?id=81357
         Therefore maxSdkVersion needs to be set to 22 instead of 19 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="22"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="22"/>

This should mean you only see the Permission > Storage appear on debug builds on Marshmallow. If your release build doesn't need the storage permissions at all, then you can omit the release/AndroidManifest.xml entries

You'll still need to request the runtime permission when you launch the debug version of your app.

Perhaps LeakCanary could store it's heap dumps in the app's external cache directory instead of Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS); ? That would mean you couldn't easily copy the heap dumps off the device using adb though.

I have the same issue on my Nexus 5 (android 6 on board). :(
The workaround mentioned above is not working.

@Zeliret Are you requesting the Storage permission using Runtime Permissions when you launch the debug app?

Well, I turned on this permission in the settings and now it works. :)

Our app conditionally requests the external storage permission in various flows, but if the user doesn't need it, we don't block usage of the app. With this issue, I can't use LeakCanary on API23 devices without the permission. I'd like our debug build to work reasonably similarly to how our release build, so forcing a request at startup isn't ideal. It would be great if this storage could be migrated to internal, and if not it would be great if LeakCanary allowed apps to opt out of external storage usage.

Please also check if storage is out of space. You can check the available space in settings. When the available space is low, leak canary failed to write on storage/sdcard/download/leakcanary/. If you use android emulator, delete file by using Android Device Monitor > File Explorer.

Was this page helpful?
0 / 5 - 0 ratings