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

Activities in the Wild: Exploring the Activity Lifecycle (360|AnDev, July 2016)

Activities in the Wild: Exploring the Activity Lifecycle (360|AnDev, July 2016)

[Check out the video of this presentation from 360AnDev 2016: https://realm.io/news/activities-in-the-wild-exploring-the-activity-lifecycle-android/]

Running, or paused, or stopped, or destroyed? Oh my! As Android developers we have little control over what state our activities are in. But we do have the ability to hook into transitions between these states to respond appropriately and ensure a pleasant user experience.

Through concrete examples you will learn how the creation and destruction of your activity instances relate to what the user is doing, as well as to what the system is doing. We will explore how state is persisted (or not) in these various scenarios and also explore some little known facts about what happens to your activity in low memory situations.

Finally, we will discuss how knowing when these transitions happen has helped me deal with tricky situations, like continuing video playback while the user interacts with a full-screen overlay.

Kristin Marsicano

July 28, 2016
Tweet

More Decks by Kristin Marsicano

Other Decks in Programming

Transcript

  1. Goal for Today Empower you to reason about the Activity

    lifecycle so you can provide a smooth user experience
  2. Activity public class TickerActivity extends AppCompatActivity { private int mCount

    = 0;
 ...
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_ticker);
 setupUI();
 updateUI();
 }
 
 ... }
 TickerActivity.java: <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout ...>
 
 <TextView ... />
 
 <TextView ... />
 
 <Button … />
 
 </LinearLayout>
 activity_ticker.xml:
  3. Activity Manager Activity Manager User clicks Ticker icon on Launch

    Screen Intent: TickerActivity Spin up app process
  4. Activity Manager Activity Manager User clicks Ticker icon on Launch

    Screen Intent: TickerActivity Spin up app process Create TickerActivity instance
  5. Activity Manager Activity Manager User clicks Ticker icon on Launch

    Screen Intent: TickerActivity Spin up app process Create TickerActivity instance Move TickerActivity to Running state
  6. Activity Manager Activity Manager User clicks Ticker icon on Launch

    Screen Intent: TickerActivity Spin up app process Create TickerActivity instance Move TickerActivity to Running state
  7. Activity States State In memory? Visible to user? In foreground?

    Non-Existent No No No Stopped Yes No No Paused Yes Yes/Partially No
  8. Activity States State In memory? Visible to user? In foreground?

    Non-Existent No No No Stopped Yes No No Paused Yes Yes/Partially No Running (aka Resumed) Yes Yes Yes
  9. Activity Lifecycle Non- existent Stopped Paused Running Set of states

    Activity can be in Rules about when/how state changes
  10. Activity Lifecycle Non- existent Stopped Paused Running Set of states

    Activity can be in Rules about when/how state changes onDestroy() onCreate() onPause() onResume() onStart() onStop() Set of callback methods
  11. onCreate() Non- existent Android OS TerrificTicker Process Instance Created Ticker

    Activity mCount = 0 Stopped Instance Created onCreate()
  12. Android OS onStart() Paused onStart() Non- existent Stopped Instance Created

    onCreate() TerrificTicker Process Ticker Activity mCount = 0
  13. onResume() Running onResume() Paused onStart() Non- existent Stopped Instance Created

    onCreate() Android OS TerrificTicker Process Ticker Activity mCount = 0
  14. User Increments Count Running onResume() Paused onStart() Non- existent Stopped

    Instance Created onCreate() Android OS TerrificTicker Process Ticker Activity mCount = 0 Press button
  15. User Increments Count Running onResume() Paused onStart() Non- existent Stopped

    Instance Created onCreate() Android OS TerrificTicker Process Ticker Activity mCount = 0 Press button Ticker Activity mCount = 1
  16. User Increments Count Running onResume() Paused onStart() Non- existent Stopped

    Instance Created onCreate() Android OS TerrificTicker Process Ticker Activity mCount = 0 Press button 1 Ticker Activity mCount = 1
  17. User Presses Back Non- existent Stopped Instance Created onCreate() Paused

    Running onResume() onStart() Press Back Android OS TerrificTicker Process Ticker Activity mCount = 1 1
  18. onPause() Non- existent Stopped Instance Created onCreate() Paused Running User

    presses back onPause() onResume() onStart() Android OS TerrificTicker Process Ticker Activity mCount = 1 1
  19. onStop() onStop() Non- existent Stopped Instance Created onCreate() Paused Running

    User presses back onPause() onResume() onStart() Android OS TerrificTicker Process Ticker Activity mCount = 1
  20. onDestroy() onDestroy() Instance Destroyed Non- existent Stopped Instance Created onCreate()

    Paused Running User presses back onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 1
  21. onDestroy() onDestroy() Instance Destroyed Non- existent Stopped Instance Created onCreate()

    Paused Running User presses back onPause() onResume() onStart() onStop() Android OS TerrificTicker Process
  22. User Launches App Again Android OS User presses icon TerrificTicker

    Process Non- existent What will the user see? 0 (0) 1 (1)
  23. Answer: (0) Android OS TerrificTicker Process Ticker Activity mCount =

    0 0 Non- existent Stopped onCreate() Paused Running onResume() onStart()
  24. TickActivity is Running onDestroy() Non- existent Stopped onCreate() Paused Running

    onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 2 0 2
  25. User Presses Home onDestroy() Non- existent Stopped onCreate() Paused Running

    onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 2 0 2 User presses Home
  26. onPause() onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume()

    onStart() onStop() 2 Android OS TerrificTicker Process Ticker Activity mCount = 2
  27. onStop() onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume()

    onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 2
  28. User Launches App Again Android OS User presses icon TerrificTicker

    Process Ticker Activity mCount = 2 Stopped What will the user see? 0 (0) 2 (2)
  29. Answer: (2) onDestroy() Non- existent Stopped onCreate() Paused Running onPause()

    onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 2 2
  30. From the Start: TickerActivity is Running onDestroy() Non- existent Stopped

    onCreate() Paused Running onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3
  31. Use Presses Save onDestroy() Non- existent Stopped onCreate() Paused Running

    onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3
  32. TickerActivity: Stopped onDestroy() Non- existent Stopped onCreate() Paused Running onPause()

    onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3 Save Activity
  33. User Presses Back onDestroy() Non- existent Stopped onCreate() Paused Running

    onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3 Save Activity
  34. Ticker Activity Moves to Stopped from Running Android OS TerrificTicker

    Process Ticker Activity mCount = 3 onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume() onStart() onStop()
  35. onStart() onStart() Android OS TerrificTicker Process Ticker Activity mCount =

    3 onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume() onStop()
  36. onStart() onStart() Android OS TerrificTicker Process Ticker Activity mCount =

    3 onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume() onStop()
  37. onStart() onResume() Android OS TerrificTicker Process Ticker Activity mCount =

    3 onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume() onStop()
  38. From the Start: TickerActivity is Running onDestroy() Non- existent Stopped

    onCreate() Paused Running onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3
  39. Use Presses Save onDestroy() Non- existent Stopped onCreate() Paused Running

    onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3
  40. TickerActivity: Paused onDestroy() Non- existent Stopped onCreate() Paused Running onPause()

    onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3 Save Activity
  41. User Presses Back Android OS TerrificTicker Process Ticker Activity mCount

    = 3 Save Activity onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume() onStart() onStop()
  42. User Presses Back Android OS TerrificTicker Process Ticker Activity mCount

    = 3 onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume() onStart() onStop()
  43. TickerActivity: Running onDestroy() Non- existent Stopped onCreate() Paused Running onPause()

    onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3
  44. Entire Lifetime (Instance Lifetime) Instance Lifetime onDestroy() Non- existent Stopped

    onCreate() Paused Running onPause() onResume() onStart() onStop()
  45. Entire Lifetime Visible Lifetime Visible Lifetime onDestroy() Non- existent Stopped

    onCreate() Paused Running onPause() onResume() onStart() onStop()
  46. Entire Lifetime Foreground Lifetime Visible Lifetime onDestroy() Non- existent Stopped

    onCreate() Foreground Lifetime Paused Running onPause() onResume() onStart() onStop()
  47. User Presses Home onDestroy() Non- existent Stopped onCreate() Paused Running

    onPause() onResume() onStart() onStop() User presses home 3 Android OS TerrificTicker Process Ticker Activity mCount = 3
  48. onPause() onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume()

    onStart() onStop() 3 Android OS TerrificTicker Process Ticker Activity mCount = 3
  49. onStop() onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume()

    onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3
  50. User Plays Pokemon GO onDestroy() Non- existent Stopped onCreate() Paused

    Running onPause() onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3 Pokemon GO Process VideoActivity
  51. Uh oh… onDestroy() Non- existent Stopped onCreate() Paused Running onPause()

    onResume() onStart() onStop() Android OS TerrificTicker Process Ticker Activity mCount = 3 VideoPlayer Process VideoActivity
  52. Ticker Process Gets Killed onDestroy() Non- existent Stopped onCreate() Paused

    Running onPause() onResume() onStart() onStop() X Android OS TerrificTicker Process Ticker Activity mCount = 3 VideoPlayer Process VideoActivity X
  53. TickerActivity Jumps to Non- Existent onDestroy() Non- existent Stopped onCreate()

    Paused Running onPause() onResume() onStart() onStop() X Android OS VideoPlayer Process VideoActivity
  54. onSaveInstanceState() public class TickerActivity extends AppCompatActivity {
 
 private static

    final String KEY_TICKER_COUNT = "ticker_count";
 ...
 
 @Override
 protected void onSaveInstanceState(Bundle outState) {
 super.onSaveInstanceState(outState);
 outState.putInt(KEY_TICKER_COUNT, mCount);
 } ...
 }

  55. public class TickerActivity extends AppCompatActivity {
 
 ... 
 @Override


    protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_ticker);
 setupUI();
 
 if (savedInstanceState != null) {
 mCount = savedInstanceState.getInt(KEY_TICKER_COUNT, 0);
 }
 
 updateUI();
 } ...
 }
 Using State Bundle
  56. Activity Record Stored 3 Activity Record Store onSaveInstanceState ticker_count: 3

    TerrificTicker Instance A Record ticker_count: 3 Instance A
  57. User Launches App Activity Record Store TerrificTicker Instance A Record

    ticker_count: 3 3 Recreated Instance A onCreate ticker_count: 3
  58. onPause • save vital data • typically stop animations or

    other things consuming CPU • should be quick
  59. Displaying Location • Show user their location • Minimize battery

    usage • Maximize precision when user is actively looking at my map
  60. Displaying Location: Which Callbacks? • Start sampling - onStart •

    Set higher sampling rate/accuracy - onResume • Set lower sampling rate/accuracy - onPause • Stop sampling - onStop onDestroy() Non- existent Stopped onCreate() Paused Running onPause() onResume() onStart() onStop()
  61. Video Playback • User starts video activity • User presses

    a transparent settings activity • video should keep playing!
  62. Video Playback: Which Callbacks? • initialize player - onCreate •

    start playback - onStart • stop playback - onStop • release player resources - onDestroy