Here is my transcription of two sessions from Day 1, 05.27.09, of the Google I/O 2009. Per my usual, the following is a combination of live quotes from the speaker, notes off the slides, some paraphrase and a few of my own asides.
Chris Nesiadek’s presentation on Android’s Interaction Design was my favorite of the day.
*****
Pixel Perfect Code: How to Marry Interaction and Visual Design the Android Way
Chris Nesiadek
Structure Behavior Expression
What makes Android unique?
Core Principles of Interaction design: Structure -> Behavior -> Expression
Roots grounded in architecture. Blueprint illustrates structure. Doors, elevators, light switches are elements of behavior – how will happen. Structure and Behavior comes together in the final pillar which is expression.
Framework Structure and Flow
What makes the Android User Experience unique:
* Multi-tasking supported by background processing : The data was held in a stateful place. How to allow people to act on data.
* Ongoing and event-driven notifications : ongoing indicates progress, event-driven indicates something has happened (email arrived, etc)
* Real-time data views through widgets and live folders : implemented widgets and live folders in Cupcake 1.5 – The theme of acting on data from the desktop
* Any application can pick and choose which intents they want to take : Android is about activities and tasks that share intents, rather than applications
* Use the hooks, re-use of components from intents is easy : Most platforms are all about a simple linear path, you got in and out of paths. We think more in terms of a stream, you can hook in on intents and the user can use data rather than stay silo’d.
Framework Basics
* The representative Android device is a happy marriage of hardware and software. Shows a diagram of the Vodafone HTC Magic Android phone, which has a different layout of buttons than the T-Mo G1.
* Portrait and Landscape. The G1 is a classic QWERTY slider. Important to not over look landscape mode. Definitely keep it in mind. The SDK can support different screen sizes and densities. 99% of our building block layouts will accommodate landscape. You use a great deal of real estate in landscape.
* Focus & menus : Because we support both touch and trackball navigation, there is not really focus in touch but in using trackball uses focus. Don’t use focus in touch until you press or trackball select.
* Main menus are global; they relate to an activity as a whole. Think of the main menu as comprised of global functions, use the more button if you have more than 5 or 6.
* Contextual menus aka Long Press are focused on a specific item.
* What to do with the More Menu? More menus let you add less relevant tertiary information or functions.
A basic example: Gmail
Some things to keep in mind
* Design for speed and simplicity
Keep hierarchy as flat as possible
Minimize onscreen actions
load data rather than asking a user to wait to see a fully fleshed out page aka lazy load
* Think about activity streams as opposed to linear actions
Design your app to have hooks across the framework
Make it so users can act on the data they see.
Onscreen Behavior
* Bringing screens to life with what we have to offer
Layer in behaviors in Gmail
Download Google IO calendar -> compresses a lot of information into one list that can be expanded
My favorite behavior – ability to drag and drop for user organized list view.
For as much as we think we know what we are doing, we don’t. Implement features and get feedback from the user.
* A word about Toasts. If some is going to be harmful for the user don’t use a Toast, then use a dialog to alert them. [Jen says: Toast?]
* Expected interaction and unexpected delight. Make behaviors fun and cute. The team took the time to make behaviors that amuse the user.
Expression – The Third Pillar
If Structure and Behavior is 80% of your work, then Expression is the next 20% of the time building your app. Expression is focusing on details.
Charles Eames – “The details are the details, they make a product.”
Chris the speaker – “It is gut check time when you get to this part of the process.”
* The aesthetics of an application help call attention to the key tasks you have made the core of your application experience.
* API demos are a great place to start your toolkit : animation, toast, etc.
* Consider using 9 patches or 9 patch techniques when you can – scalable images – notion of polish
http://developer.android.com/guide/developing/tools/draw9patch.html.
* Want to reduce banding in gradients (due to gradients being stretched). In 1.5 you can dither in run-time with 9 patches, which compresses the image to reduce the file size in APK.
* Marquee is an option for long text strings in Cupcake 1.5 – good for localization
* Consider using the built-in scalable pixel units typography.
* Want to match a pixel perfect layout? Use Hierarchy Viewer
Expression
TIps and Tricks
* Want to learn more?
Check out Romain Guy, Joe Onarato, and David Spark’s presentations
Today – David: Mastering the Android Framework
Our Plans for the Future
We’re continuing to innovate with each release
*UI Guidelines
First section of living UI guidelines is available online today
*Make sure to update the SDK
*****
Google App Engine
Brett Slatkin
Agenda
List Properties
Merge-join
MOderator tinyurl/complextalk
List properties
What is a list property?
*Property in the datastore that has multiple values
* An ordered list that maintains its order
*Queried with an equals filter
Any value in the list may cause a match
Sort order not useful without a composite index
*As easy as:
example
Why use?
*Densely pack information
Track lists of related items
Use multiple parallel properties for storing “tuple” like data
*Easy: compare to this one-to-many query
*Great for answering set-membership questions
eg Which users like the color yellow?
* Great fan out capability: cut across all your data
* Avoids storage overhead
* Gotchas : Uses more CPU for serializing/deserializing the entity when it’s accessed
Works with sort orders only if querying a single list property; otherwise indexes explode.
Concrete example: Microblogging
*Essentially: Publish/subscribe, broadcast/multicast; users send a single message that goes to many other users
* It’s a great example of fan out: One user action causes a lot of work, work leaves large amount of data to surface
* Fan out, the naive way, can be inefficient, require duplicate data. Send a copy of a message to N users.
* Efficient fan out should not duplicate any data: only overhead is coast of indexes
Shows an example of tables for traditional database.
How would you do this in SQL? YOu would use a join:
* No joins in App Engine – How do we do this? List properties to the rescue.
results = db.GqlQuery( “Select * from Message” “Where receivers = :1″, me) (This is how Jaiku works)
With JDO (more complex example)
*Index writes are done in parallel on BigTable
Fast: update a list property of 1000 items with 1000 row writes simultaneously
Scales linearly with number of items
Limited to 5000 indexed properties per entity
*Storage cost same as SQL
*Downside: Serialization overhead
*Writes must package all list values into one serialized protocol buffer: Ok because writes are relatively infrequent
* But queries must unpackage all result entities
*Querying for message should only return the message information, we don’t care about the list properties after querying; this is why inner joins are useful
*What if we could selectively skip certain properties when querying?
Would avoid the seria cost
Ideally, it would great to this in GQL
Solution : Relation index entities
*Split the message into two entities
Message model contains the info we care about
MessageIndex has only relationships
*PUt entities int the same entity group for transactions: Message Index _> (parent) -> Message
* Do a key only query to fetch the MessageIndexes
*Transform returned keys to retrieve parent entity
* Fetch Messages entities in batch
* Our datastore works like this under the covers
Gives a test demo
Conclusion:
*Performance is much better: writes same cost, reads ~10x faster
*Best of both worlds with list properties: low storage cost, low CPU cost
*Even better: scalable indexes
Need more indexes? write multiple relation index entities per message
add indexes in the background (with task queue)
No need for schema migration
Shows diagram for scalable indexes
Merge-Join
What is it?
*People say app engine doesn’t support joins — not totally true, we do
*GAE support merge-join queries
A type of self-join query; join a table with itself
Combine many equality tests into a single query
Determines Venn diagram overlaps
* Great for exploring your data:
* No need to build indexes in advance, ad-hoc queries, reduces cost
*Provides advanced functionality: example query in gmail, various labels, read/unread, etc.
Example” “””Select * from Animal Where Color = ‘spots’ and has = ‘horns’ and legs = 4″””
How does merge-join work?
*Not available in raw Bigtable: similar in optimizations in other DB systems
* All property indexes are stored in sorted order
*datastore does a merge-sort at runtime
*Uses a zig-zag algorithm to efficiently join tables
Concrete example: Social Graph
*Essentially: Users have a profile and a set of friends: Use merge-join on list properties — magic!
*Answer queries about relationships: Who are my friends, who are my friends in SF? Which friends do I have in common with person P? Which friends do I have in common with person P in SF?
* shows how you would do this in a relational database
*SQL query to find friends of user X (demo code)
*To also filter by location, add (demo code)
*SQL query to find friends common to X and Y (demo code)
*No inner joins in App Engine, what now? We do have merge-join; we can do self-joins.
“””SELECT * from Person where friends = :1 and friends = :2 and location = ‘San Francsico ‘ “””
Merge-Join Performance
*Scales with number of filters and size of result set: best for queries with fewer results
*Similar access performance as list properties
Same read/write speed
*Gotchas; Watch out for pathological datasets (ha!)
Too many overlapping values – lots of zigzagging
Doesn’t work with composite indexes because of exploding index combinations
That means you can’t apply sort orders: Must sort in memory.
Wrap Up
*Use list properties and merge-join for many things:
Fan-out
Geospatial info
Relationship graps
Fuzzy values
* Think about how to convert your queries into set memberships tests
* Compute membership at write time, enjoy fast reads!
pubsub-test.appspot.com
dagpeople.appspot.com
Questions?