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

The Dangers of SharedPreferences: An API Allegory

Kurt Nelson
November 20, 2018

The Dangers of SharedPreferences: An API Allegory

SharedPreferences has been in the framework and recommended since day 1. However, it has some hidden nuances and pitfalls that can lead to flakiness in production.

Learn when you should use it and how to write robust APIs with it.

Kurt Nelson

November 20, 2018
Tweet

More Decks by Kurt Nelson

Other Decks in Technology

Transcript

  1. Designing OS APIs Writing a good API for a library

    isn’t easy. RxJava is an example of a largish rewrite. But apps pick what version they want to use and bundle.
  2. Designing OS APIs Once an OS API has shipped, we’re

    stuck dealing with it. Flash still isn’t dead 20 years later. Has anyone ever tried to modify a Unix system call?
  3. Designing Android Framework APIs The Android Framework is slow moving.

    Unlike an old Linux kernel running the same software on an unchanging metal machine somewhere, new devices are being shipped running old Android. Google Glass EE still runs KitKat. Even if you are aggressive, you probably still have a minSDK of 21/Lollipop.
  4. Designing Android Framework APIs What we write today will not

    be widely available for a year or two. Hardware is hard and inflexible once shipped, you are building software that is sold on a shelf in a store.
  5. Designing Android Framework APIs What we write today will not

    be widely available for a year or two. Hardware is hard and inflexible once shipped, you are building software that is sold on a shelf in a store. Your job is to calculate all the possible tradeoffs to solving a problem, and then make a decision on behalf of all of your users forever.
  6. Designing Android Framework APIs Hide as much implementation complexity from

    the user while being versatile enough for many use cases. Silently handle as many failure modes as you can while informing your consumer when things do go wrong. Be at least as performant but hopefully better than a naive hand-rolled solution. Operate safely in a shared environment. Make hard engineering decisions on behalf of your user.
  7. SQLite • Fast • Fully async • Configurable ◦ Write-ahead

    logging • Manually written queries • Migrations • Overhead to open • Plumbing to Rx • Bad for storing byte[]
  8. SQLite • Fast • Fully async • Configurable ◦ Write-ahead

    logging • Manually written queries • Migrations • Overhead to open • Plumbing to Rx • Bad for storing byte[] Room Helps
  9. initializeAndReadAll(); writeAsync(String key, byte[] stuff); // Cheap flash fails. writeAsync(otherKey,

    otherStuff); // In-memory cache saves the day and both write. byte[] read(String key);
  10. initializeAndReadAll(); writeAsync(String key, byte[] stuff); // Cheap flash fails //

    In memory cache masks the failure. byte[] read(key); // The OS kills your process ???
  11. Why does no one notice? The device you are developing

    on probably has better than average flash. The store is serialized and written as a whole. Any single successful write will persist any pending changes. SharedPreferences (especially in Pie) tries to do the right thing and tell you when things fail.
  12. apply() has no callback whatsoever. They do ensure changes were

    committed to memory on return of apply(). Changes may or may not make it to disk.
  13. SharedPreferencesImpl (lollipop-mr1) If using apply, your application will never hear

    about these types of failure. When using commit, you’ll just get “false” (newer versions are very similar, they have more code tracking timestamps)
  14. Kind of. You can’t tell it to stick itself in

    your app’s cache directory so it’ll count as real data.
  15. I’m sad now Use Room! Square’s Tape is good for

    offline storage of transaction data. Just use java.io.File for authentication tokens and such. Okio is nice for bigger files, streaming and/or partial reads. The major image libraries all have great caching layers. If you like being sad, take a look at the source code for AtomicFile!
  16. An API allegory (If this tale is the type that

    keeps you up at night, my team is hiring) The Dangers of SharedPreferences Kurt Nelson Uber Mobile Platform @kurtisnelson [email protected]