Android App Mistakes:
Avoiding the Anti-Patterns
   by Mark Murphy, CommonsWare
Introduction
• Anti-Patterns
 • Code pollution
 • Fatal assumptions
• Goal: help you avoid these anti-patterns
 • Develope...
Everlasting Services

• What is the Anti-Pattern?
 • Trying to have a service “always running”,
    instead of periodicall...
Everlasting Services
• Why Is This Important?
 • Android kills off old services to reclaim
    RAM
  • Users kill off serv...
Everlasting Services
• What is the Right Answer?
 • Rare use cases for everlasting services
   • VOIP app
 • Otherwise, ai...
Background Control

• What is the Anti-Pattern?
 • Implementing a polling mechanism
    without any sort of user control
 ...
Background Control
• Why Is This Important?
 • Users may blame your app
   • Battery drain
   • RAM consumption
 • Users m...
Background Control

• What is the Right Answer?
 • If polling, let user choose period
    (including “never”)
  • If everl...
Background Becomes Foreground


• What is the Anti-Pattern?
 • Doing significant processing in
    background callbacks
   ...
Background Becomes Foreground

• Why Is This Important?
 • Normally, background processing is CPU-
    capped at ~10%
  • ...
Background Becomes Foreground

• What is the Right Answer?
 • BroadcastReceiver delegates to
    IntentService
  • IntentS...
Boot-Time Services

• What is the Anti-Pattern?
 • Configuring a BroadcastReceiver to
    respond to the BOOT_COMPLETED
   ...
Boot-Time Services
• Why Is This Important?
 • Too many boot-time services slows the
    boot down for user
   • Lots of p...
Boot-Time Services

• What is the Right Answer?
 • Use it only if truly necessary (e.g., restore
    AlarmManager alarms)
...
Using Multiple Processes

• What is the Anti-Pattern?
 • Forcing Android to use more than one
    process for your applica...
Using Multiple Processes

• Why Is This Important?
 • Each process takes up a significant chunk
    of RAM
 • More active p...
Using Multiple Processes

• What is the Right Answer?
 • Just avoid multiple processes!
 • Remote services/AIDL are for th...
Use Mutable Statics

• What is the Anti-Pattern?
 • Using static data members for more than
    final “constant” values
   ...
Use Mutable Statics
• Why Is This Important?
 • Android can close components to
    reclaim memory...if memory can be GC’d...
Use Mutable Statics
• What is the Right Answer?
 • Avoid mutable statics where possible
 • Be very careful with the ones y...
Leak Like a Sieve

• What is the Anti-Pattern?
 • Register...and do not unregister
 • Acquire...and do not release
 • Assi...
Leak Like a Sieve
• Why Is This Important?
 • Once again, the issue is GC
 • Registered listeners, etc. are held in static...
Leak Like a Sieve
• What is the Right Answer?
 • Aim to use lifecycle pairs
   • Register in onCreate(), release in
      ...
Force Wrong UI

• What is the Anti-Pattern?
 • Adding an Exit menu choice or button
 • Trying to create a blocking modal d...
Force Wrong UI
• Why Is This Important?
 • Android has a style all its own
   • Different, not necessarily bad
 • Breaking...
Force Wrong UI
• What is the Right Answer?
 • Use Android navigation and APIs
    naturally, not trying to emulate some
  ...
Ignore Screen Sizes
• What is the Anti-Pattern?
 • Focusing on one screen size
 • Focusing on customizing for individual
 ...
Ignore Screen Sizes
• Why Is This Important?
 • Your app may not work well on existing
    devices
 • Your app may not wor...
Ignore Screen Sizes
• What is the Right Answer?
 • Write to be resolution-independent
   • RelativeLayout
   • Don’t use p...
Assume Touch

• What is the Anti-Pattern?
 • Writing an application that assumes the
    existence of a touchscreen and do...
Assume Touch
• Why Is This Important?
 • Not all Android devices will be
    touchscreens
   • Television set-top boxes
  ...
Assume Touch
• What is the Right Answer?
 • If your app only makes sense with
    touchscreen, require it via the manifest...
Make Busy App Widgets

• What is the Anti-Pattern?
 • Trying to update an app widget every
    second...from your code
   ...
Make Busy App Widgets
• Why Is This Important?
 • App widgets cross the process boundary
    on every update
   • Your cod...
Make Busy App Widgets
• What is the Right Answer?
 • App widgets are largely static or driven
    by user input
  • Update...
Assume Unlimited Data
• What is the Anti-Pattern?
 • Assuming users have unlimited SMS plans
   • Using SMS for chatty app...
Assume Unlimited Data
• Why Is This Important?
 • “Unlimited” SMS or data only available in
    some markets to some users...
Assume Unlimited Data
• What is the Right Answer?
 • Allow user controls over chattiness or
    refresh periods
 • Pay att...
Reach Past the SDK
• What is the Anti-Pattern?
 • Using reflection to access public classes,
    etc. that are not part of ...
Reach Past the SDK
• Why Is This Important?
 • Your app may break on today’s or
    tomorrow’s phones
 • Broken apps = unh...
Reach Past the SDK
• What is the Right Answer?
 • Stick to the SDK
 • Work with the core Android team to
    figure out how...
Anti-Patterns, OEM Style

• Plenty of anti-patterns for creating Android
  devices
• Impacts ability of developers to deli...
Breaking the SDK
• What is the Anti-Pattern?
 • Changing Android and breaking API
 • Changing Android and changing behavio...
Breaking the SDK
• Why Is This Important?
 • Broken SDK means some apps break
   when run on your device
   • Until develo...
Breaking the SDK
• What is the Right Answer?
 • Test, test, test!
   • CTS is nowhere near sufficient
 • Developer device s...
Hamper Developers

• What is the Anti-Pattern?
 • Break access to DDMS
 • Block non-Market app installs
 • Innovate withou...
Hamper Developers
• Why Is This Important?
 • Users buy these devices for the apps
 • Important for apps to work well on y...
Hamper Developers
• What is the Right Answer?
 • End users are not your only user base
    you need to think about
 • Have...
Block Replacement Firmware


• What is the Anti-Pattern?
 • Using cryptographic signing to prevent
    people from replaci...
Block Replacement Firmware

• Why Is This Important?
 • Segment of your user base values this
   • Can result in bad PR
 •...
Block Replacement Firmware

• What is the Right Answer?
 • Best = support replacement firmware
   • ADP1, ADP2
 • Great = e...
Summary

• Avoid anti-patterns
 • Better for your apps
 • Better for your devices
 • Better for Android overall
Contact Info

• http://commonsware.com
• mmurphy@commonsware.com
• http://commonsware.com/blog
• Twitter: commonsguy
• +1....
Upcoming SlideShare
Loading in …5
×

Android App Mistakes: Avoiding the Anti-Patterns

8,327 views

Published on

There are many mistakes that developers and OEMs can make that affect not only users, but other developers as well. This presentation reviews these anti-patterns and the ways to address them. Developed from the "Code Pollution" blog post series on AndroidGuys.com. From a May 2010 presentation in Lund, Sweden.

Published in: Technology
3 Comments
28 Likes
Statistics
Notes
No Downloads
Views
Total views
8,327
On SlideShare
0
From Embeds
0
Number of Embeds
195
Actions
Shares
0
Downloads
293
Comments
3
Likes
28
Embeds 0
No embeds

No notes for slide

Android App Mistakes: Avoiding the Anti-Patterns

  1. 1. Android App Mistakes: Avoiding the Anti-Patterns by Mark Murphy, CommonsWare
  2. 2. Introduction • Anti-Patterns • Code pollution • Fatal assumptions • Goal: help you avoid these anti-patterns • Developers • OEMs
  3. 3. Everlasting Services • What is the Anti-Pattern? • Trying to have a service “always running”, instead of periodically running or running when your activity is on-screen • startService() without a stopService() or stopSelf()
  4. 4. Everlasting Services • Why Is This Important? • Android kills off old services to reclaim RAM • Users kill off services they do not understand • Task killer • Settings > Applications > Services
  5. 5. Everlasting Services • What is the Right Answer? • Rare use cases for everlasting services • VOIP app • Otherwise, aim to keep the service out of RAM when not actively doing work • AlarmManager
  6. 6. Background Control • What is the Anti-Pattern? • Implementing a polling mechanism without any sort of user control • Implementing an everlasting service without user option to not have it
  7. 7. Background Control • Why Is This Important? • Users may blame your app • Battery drain • RAM consumption • Users may kill or uninstall your app to regain control
  8. 8. Background Control • What is the Right Answer? • If polling, let user choose period (including “never”) • If everlasting service, let user say “no” • VOIP app...but only for outgoing calls
  9. 9. Background Becomes Foreground • What is the Anti-Pattern? • Doing significant processing in background callbacks • onReceive() • onCreate() / onStart() / onDestroy()
  10. 10. Background Becomes Foreground • Why Is This Important? • Normally, background processing is CPU- capped at ~10% • During those callbacks, priority changes to normal foreground priority • May impact real foreground (e.g., game)
  11. 11. Background Becomes Foreground • What is the Right Answer? • BroadcastReceiver delegates to IntentService • IntentService does everything in onHandleIntent() • Or other means of using background threads instead of work in callbacks
  12. 12. Boot-Time Services • What is the Anti-Pattern? • Configuring a BroadcastReceiver to respond to the BOOT_COMPLETED broadcast Intent
  13. 13. Boot-Time Services • Why Is This Important? • Too many boot-time services slows the boot down for user • Lots of process churn • May cause those broadcasts to be delayed for everyone
  14. 14. Boot-Time Services • What is the Right Answer? • Use it only if truly necessary (e.g., restore AlarmManager alarms) • Do not do significant work right away • Wait for later trigger or user interaction
  15. 15. Using Multiple Processes • What is the Anti-Pattern? • Forcing Android to use more than one process for your application • Remote services for internal use • Process attributes in manifest • Forking processes from JVM
  16. 16. Using Multiple Processes • Why Is This Important? • Each process takes up a significant chunk of RAM • More active processes = more likely other things get kicked out of RAM • If user feels RAM is over-utilized, more likely to come after you with task killer
  17. 17. Using Multiple Processes • What is the Right Answer? • Just avoid multiple processes! • Remote services/AIDL are for third-party use, not your own • Be careful on forking system processes (e.g., interpreters, built-in binaries)
  18. 18. Use Mutable Statics • What is the Anti-Pattern? • Using static data members for more than final “constant” values • Caching • Cross-component communication
  19. 19. Use Mutable Statics • Why Is This Important? • Android can close components to reclaim memory...if memory can be GC’d • Static references inhibit GC • Static references to things that hold onto components defeats Android’s intentions
  20. 20. Use Mutable Statics • What is the Right Answer? • Avoid mutable statics where possible • Be very careful with the ones you need • Ensure they do not hold references (direct or indirect) to activities, services, etc.
  21. 21. Leak Like a Sieve • What is the Anti-Pattern? • Register...and do not unregister • Acquire...and do not release • Assign to static...and not null out reference later
  22. 22. Leak Like a Sieve • Why Is This Important? • Once again, the issue is GC • Registered listeners, etc. are held in static references inside of Android • Must get those released • Free up RAM • Stop events from continuing to fire
  23. 23. Leak Like a Sieve • What is the Right Answer? • Aim to use lifecycle pairs • Register in onCreate(), release in onDestroy(), etc. • Use onDestroy() as “backstop”, releasing everything registered or acquired • Exception handling and finally {} block
  24. 24. Force Wrong UI • What is the Anti-Pattern? • Adding an Exit menu choice or button • Trying to create a blocking modal dialog • Otherwise attempting to pretend Android is some other OS
  25. 25. Force Wrong UI • Why Is This Important? • Android has a style all its own • Different, not necessarily bad • Breaking that style will cause some user confusion...or developer confusion when users do not behave as expected
  26. 26. Force Wrong UI • What is the Right Answer? • Use Android navigation and APIs naturally, not trying to emulate some other model • Navigation: pretend you are writing a Web application • Flow is much like a Web browser
  27. 27. Ignore Screen Sizes • What is the Anti-Pattern? • Focusing on one screen size • Focusing on customizing for individual screen sizes • Instead of coming up with layouts, etc. that work across sizes
  28. 28. Ignore Screen Sizes • Why Is This Important? • Your app may not work well on existing devices • Your app may not work well on future devices • Many new screen sizes are coming
  29. 29. Ignore Screen Sizes • What is the Right Answer? • Write to be resolution-independent • RelativeLayout • Don’t use pixel dimensions • Test on a wide range of layouts to confirm your independence actually works
  30. 30. Assume Touch • What is the Anti-Pattern? • Writing an application that assumes the existence of a touchscreen and does not mandate it via the manifest • Not testing an application via the D-pad and keyboard alone
  31. 31. Assume Touch • Why Is This Important? • Not all Android devices will be touchscreens • Television set-top boxes • Low-end smartphones / high-end “feature phones”
  32. 32. Assume Touch • What is the Right Answer? • If your app only makes sense with touchscreen, require it via the manifest • If your app could be used by D-pad or equivalent, test it out, make sure it makes sense • “Tab order” issues
  33. 33. Make Busy App Widgets • What is the Anti-Pattern? • Trying to update an app widget every second...from your code • Rolling your own timer • Faking an animation
  34. 34. Make Busy App Widgets • Why Is This Important? • App widgets cross the process boundary on every update • Your code -> home screen process • IPC is expensive in terms of CPU time • Hence, expensive for battery
  35. 35. Make Busy App Widgets • What is the Right Answer? • App widgets are largely static or driven by user input • Update the app widgets on user demand or slow timers • 30 minute minimum for updatePeriodMillis
  36. 36. Assume Unlimited Data • What is the Anti-Pattern? • Assuming users have unlimited SMS plans • Using SMS for chatty app protocols • Assuming users have unlimited data plans • Constantly refreshing or downloading data
  37. 37. Assume Unlimited Data • Why Is This Important? • “Unlimited” SMS or data only available in some markets to some users • Everybody else pays by the message or MB • Even “unlimited” usually comes with caps • Net: costs users money or capability
  38. 38. Assume Unlimited Data • What is the Right Answer? • Allow user controls over chattiness or refresh periods • Pay attention to WiFi vs. mobile data connections • WiFi is less prone to costing users money
  39. 39. Reach Past the SDK • What is the Anti-Pattern? • Using reflection to access public classes, etc. that are not part of the SDK • Accessing undocumented content providers • Assuming existence of certain binaries
  40. 40. Reach Past the SDK • Why Is This Important? • Your app may break on today’s or tomorrow’s phones • Broken apps = unhappy users • Will they think ill of you...or Android? • Weakens arguments against OEMs
  41. 41. Reach Past the SDK • What is the Right Answer? • Stick to the SDK • Work with the core Android team to figure out how to open more up • Coordinate SDK-hack wrappers • Strength in numbers
  42. 42. Anti-Patterns, OEM Style • Plenty of anti-patterns for creating Android devices • Impacts ability of developers to deliver quality apps for your device • Impacts user satisfaction with apps, your device, and Android overall
  43. 43. Breaking the SDK • What is the Anti-Pattern? • Changing Android and breaking API • Changing Android and changing behavior of documented resources • Inadequately setting expectations • Example: contacts and Facebook
  44. 44. Breaking the SDK • Why Is This Important? • Broken SDK means some apps break when run on your device • Until developers spend extra effort trying to work around your errors • Broken expectations cause angst for users and developers alike
  45. 45. Breaking the SDK • What is the Right Answer? • Test, test, test! • CTS is nowhere near sufficient • Developer device seeding program • Direct • Through services (DeviceAnywhere)
  46. 46. Hamper Developers • What is the Anti-Pattern? • Break access to DDMS • Block non-Market app installs • Innovate without adequate explanation • Example: CDMA on Android 1.5
  47. 47. Hamper Developers • Why Is This Important? • Users buy these devices for the apps • Important for apps to work well on your device • Users will think poorly of your device • Users will think poorly of Android
  48. 48. Hamper Developers • What is the Right Answer? • End users are not your only user base you need to think about • Have developer programs for communication and support • Don’t screw up the firmware too bad
  49. 49. Block Replacement Firmware • What is the Anti-Pattern? • Using cryptographic signing to prevent people from replacing firmware
  50. 50. Block Replacement Firmware • Why Is This Important? • Segment of your user base values this • Can result in bad PR • Never know when a replacement firmware may increase the value of your device, or give you access to firmware talent
  51. 51. Block Replacement Firmware • What is the Right Answer? • Best = support replacement firmware • ADP1, ADP2 • Great = endorse replacement firmware • Nexus One • OK = “fig leaf” on firmware issue
  52. 52. Summary • Avoid anti-patterns • Better for your apps • Better for your devices • Better for Android overall
  53. 53. Contact Info • http://commonsware.com • mmurphy@commonsware.com • http://commonsware.com/blog • Twitter: commonsguy • +1.484.350.4004

×