Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Stricter StrictMode

Kurt Nelson
September 25, 2017

Stricter StrictMode

Enabling StrictMode in development builds of your Android apps can prevent jank.

Kurt Nelson

September 25, 2017
Tweet

More Decks by Kurt Nelson

Other Decks in Programming

Transcript

  1. What is StrictMode? “StrictMode is a developer tool which detects

    things you might be doing by accident and brings them to your attention so you can fix them.”
  2. What is StrictMode? “StrictMode is a developer tool which detects

    things you might be doing by accident and brings them to your attention so you can fix them.”
  3. What is StrictMode? “StrictMode is a developer tool which detects

    things you might be doing by accident and brings them to your attention so you can fix them.” runs a penalty
  4. What is StrictMode? First appeared in Gingerbread release in 2010.

    New detectors added over time including in Oreo. Can be enabled device wide or per-app.
  5. Even if you have code review, tiny mistakes will slip

    through and cause seemingly random performance issues in the wild. Especially on low-end devices with low quality flash.
  6. Example 60fps ~= 16 milliseconds per frame User is scrolling

    smoothly through a list Data is needed from disk The next needed bytes are across a cache line, taking >16ms to load Just dropped at least one frame
  7. Detectors: Thread Custom Slow Calls - Code can noteSlowCall() to

    trigger Disk Reads - Reading from disk can be slow and unpredictable Disk Writes - Writing to disk can be even slower and more unpredictable Network - Using the network blocks the thread until it completes Resource Mismatches - Using the wrong type to get a resource causes extra casting or wrong data. NEW! Unbuffered IO - Unbuffered IO operations are expensive
  8. Detectors: Virtual Machine (Leaks) Activity Leaks - Detect leaks of

    Activity subclasses Leaked Closable Objects - Detect when an Closeable or other object with a explicit termination method is finalized without having been closed. Leaked Registration Objects - Detect when a BroadcastReceiver or ServiceConnection is leaked during Context teardown. Leaked SqlLite Objects - Detect when an SQLiteCursor or other SQLite object is finalized without having been closed.
  9. Detectors: Virtual Machine (Misc) Cleartext Network - Prevent any cleartext

    traffic from escaping NEW! Content Uri Without Permission - Detect when the calling application sends a content:// Uri to another app without granting permission. File Uri Exposure - Detect when the calling application exposes a file:// Uri to another app. NEW! Untagged Sockets - Detect any sockets in the calling app which have not been tagged using TrafficStats.
  10. public void onCreate() { … if (DEVELOPER_MODE) { StrictMode.setThreadPolicy( new

    StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() // show violations in logcat .build()); StrictMode.setVmPolicy( new StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() // show violations in logcat .build()); } …
  11. There is a bug https://issuetracker.google.com/issues/36951662 StrictMode policies set during Application.onCreate

    are clobbered upon the return of execution to ActivityThread in Jelly Bean through Oreo. A fix is committed and will activate itself when targeting a future API Level.
  12. Penalties Log, flash screen, dialog, dropbox, and death. Dropbox is

    only useful if you are a system signature app. (it's a persisted blob friendly logcat equivalent, accessible with root)
  13. Penalties For greenfield apps, penaltyDeath() is recommended. If you have

    an existing app, dialog is probably your best option as you definitely already have violations. Wouldn't it be nice if you could just get a callback and decide if you want to do something about a violation? Maybe even log them somewhere?
  14. WARNING! Dangerous, unstable, slow reflection hacks ahead. *Only use in

    development builds on devices running N or O. **As with any use of private Android APIs, it will break some day.
  15. Dirty Hack - Thread Violation Callback Use reflection to grab

    the ThreadLocal violationsBeingTimed in StrictMode and overwrite it with your own subclass of ArrayList that overrides add(). Not calling super.add() has the bonus effect of stopping log, dialog, and flash thread penalties. penaltyDeath() and non-UI thread causes a different non-interceptable code path to run. The object passed to add() can be further reflected on to get information about the specific violation.
  16. Dirty Hack - VM Violation Callback Use reflection to grab

    the HashMap sLastVmViolationTime in StrictMode and overwrite it with your own subclass of HashMap that overrides containsKey(). Returning true from containsKey() has the bonus effect of stopping log, dialog, and flash VM penalties. penaltyDeath() follows a different code path. Unfortunately, no information about the violation itself is available here.
  17. Fixing Slow Operations Move them to a background thread. All

    of them. Ideally your app has common Executors that can be injected. AsyncTask is an option, just be sure to not leak the UI context.
  18. Fixing Resource Mismatches The type of the resource in XML

    must be the same as the type of the getter.
  19. Fixing Unbuffered I/O Buffer it with BufferedInputStream, BufferedOutputStream and friends.

    The goal is to not repeatedly go all the way to disk for one byte at a time.
  20. Fixing Leaked Activities Remove hard references to UI components after

    the activity hosting them has been destroyed. Repeated configuration changes can cause things to leak over and over. High heap utilization leads to GC, poorly timed GC can jank the app.
  21. Fixing Leaked Closeables .close() must be called at least once

    on any Closeable object. Android will eventually close it for you, but you waste memory in the meantime. Leaking SQLite cursors is more severe as native resources cannot be deallocated. Try/Finally can ensure this mistake is not made.
  22. Fixing violations leads to a more consistent experience for more

    of your users. Remember, most users are not on the latest Nexus or Pixel device.