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

Dynamic (?!) Content Providers

Dynamic (?!) Content Providers

Content Providers are a key architectural component for making Android apps work well and robustly. We'd like to use them, but we'd like to avoid writing and maintaining them. Hmm... Let's see if we can have it both ways. We'll look briefly at the purpose and implementation machinery of standard SQLite-backed content providers, and discover how -- even in the strongly typed Java world -- we can take a step toward a dynamic provider, gaining speed and fun while ditching code and bugs.

adbreind

July 30, 2014
Tweet

More Decks by adbreind

Other Decks in Programming

Transcript

  1. Dynamic (?!) Content Providers  Content Providers: the What &

    Why The (Repetitive!) Parts of a Provider  Can we make Providers Dynamic?  The Last Provider You'll Ever Write (Ideally) Adam Breindel [email protected] Bay Area Android Developer Group 29 July 2014
  2. goal • At the end of this talk, my goal

    is for you to – understand the purpose of content providers (what they're for, why they beat the alternatives) – understand the nature of providers (how they are built and what's inside) – share your frustration at the repetitive plumbing of providers & do something constructive – feel you can do something about it: use and/or contribute to a dynamic provider
  3. what? • CPs are a core piece of Android architecture

    • Both internal data stores as well as 3rd-party data stores can be, and are, exposed as CPs – e.g., contacts, phone history, media, etc. • Provide a default pattern for interoperable, cross-process persistent data access • Agnostic w.r.t. actual persistence mechanism
  4. why? • Google said we should * • REST is

    cool, let's do more of that * • Client-side cache beats 9G LTE+++. Every time. • Std pattern == more time for your real challenges • URI often makes more sense than files and tables – Implicit albeit simplistic ORM beats Binder/AIDL • Security: access, read, write, delegate… • ACTION_VIEW, ACTION_EDIT, etc. • Free Loaders and LoaderManagers • Easy access to ContentObserver support
  5. how? • Extend CP, implement methods – add on MIME

    type support – add on URI matching – publish (or at least create) a contract class • Using SQLite? Ok… – Extend SQLiteOpenHelper, implement methods – Implement SQL/DB adapter methods • Want to keep interface/implementation separate? – Isolate SQL schema from contract class…
  6. are you serious? • How often do you need to

    create new CPs? • One of those annoying tasks that's just infrequent enough that there's little motivation to simplify it • Unfortunately, that means it's tempting to avoid or omit using CPs, especially if it's something new to learn
  7. can't this be magically easier? • We're programmers, let's do

    something • Copy & paste? – not the worst thing, but begs the question • Code generation – cool, but now we've got all this code to maintain • Dynamic provider – same code (which we don't need to write) – different behavior in each project – standard implementation, driven by some config
  8. thinking about a dynamic provider • Java is statically typed

    • Does this mean we'll need to use a lot of Java reflection? • … or worse, dynamic code generation?
  9. where does a CP "touch" the rest of the world?

    • SQLite DB – program with SQL / quasi-SQL (QueryBuilder, etc.) – Java -> SQL is a required indirection layer that allows an opportunity for dynamism – SQLite itself is even more dynamic (flex columns) – (almost "too dynamic" compared to other DBs) • Cursors – turns out they are dynamic as well!
  10. what about contract classes? • Can we put the contract

    somewhere besides hard-coded Java source? • How about a resource? – easy to configure in your main app, avoids a two-way dependency between app & provider • or a text file? – allows app to "change itself" as needed, without code • ok, let's take both! – and of course you're free to publish a contract in docs etc.
  11. what's next? • This project started as a proof-of-concept –

    It is missing many useful (and possibly necessary) things • TODOs – Drive schema/DDL (optionally) from config, not just resource data – SQLite doesn't understand dates, so we use a Unix timestamp for orders, etc. – why not automate that conversion? – Support schema upgrade (within limits of course) – Multiple entities – Automate route-style URI querying for reasonable mainstream cases • Farther out – Pluggable providers (NoSQL, files, etc.) – Auto-sync/push/fetch/cache with RESTful backend (FaaS?) – …