Subbu Lakshmanan

Being aware of Android Lifecycle-I

Understanding android lifecycle through hands-on

The first of many questions in an interview for any Android Developer position would be about Life Cycles. I myself, have asked the same question to several interviewees and got definitions of life-cycles to the teeth.

For a very long time, I thought that I understood the lifecycles completely (Until last week). We work in an app that heavily uses fragments with very few activities. Last week, we were noticing some strange issues started popping out. After spending some time, we figured out that the developer who wrote, made some assumptions about the life-cycles and failed to handle the events.

My first instinct as a Developer was to look at the Android documentation and read through some blogs to refresh my understanding. However I realized that there would another time in the future I would have to do the same, If I didn't get my hands dirty by working on some hands-on exercises and really understand the android life-cycles.

I planned to spend some time over the weekend to work on few common scenarios with Android Activities and Fragments and document my understanding.

My basic Idea was to try writing a sample app to understand the following cases.

  • Single Activity
  • Single Activity with one fragment (Statically attached to activity layout /Dynamically attach using "SupportFragmentManager")
  • Single Activity with multiple fragments
  • Two Activities
  • Two Activities with one fragment each

Note: This is going to be a multi-part series in understanding android lifecycles. I am going to create a public repository to share the code. Any suggestions or feedbacks are most welcome.

Some Restrictions that I put on myself to focus on understanding the life-cycle and not to derail into other details.

  1. Spend minimum effort on typing code. Use templates as much as possible.(Android Studio provides some good samples).
  2. Keep the UI to the minimum enough to show difference. Do not spend effort in designing or making it aesthatically pleasing. Focus on writing enough debug statements to understand what's going on.
  3. Try to understand as much as possible from each example. Do not jump from one to another without understanding. This involves making notes from the debug statements, reading android documentation and of course reading blogs from the wise on the web.
    Additional Technical Restrictions:
    Even though the world has moved on to Android O with minimum support from API 23 (aka Lollipop), our app runs on custom android platform based on Kitkat.
  4. So I'm keeping the minimum Android SDK API level to 19 (aka Kitkat).
  5. I am going to stick with SupportFragmentManager rather than FragmentManager. Probably I will put up another article later comparing the both.

Let's get the hands dirty

I created a new android application project, 'LifeCyclesApp' (can't name it any other way).

Application Class

public class LifeCyclesApp extends Application {

    private static final String TAG = LifeCyclesApp.class.getSimpleName();

    //region Life-cycle apps
    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate()");
        super.onCreate();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        Log.d(TAG, "onConfigurationChanged()");
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onTerminate() {
        Log.d(TAG, "onTerminate()");
        super.onTerminate();
    }
    //endregion
}

Main Activity class


public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    //region Life-cycle events
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate()");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        Log.d(TAG, "onStart() ");
        super.onStart();
    }

    @Override
    protected void onResume() {
        Log.d(TAG, "onResume() ");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause() ");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.d(TAG, "onStop() ");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy() ");
        super.onDestroy();
    }
    //endregion
}

The UI is very simple. It has nothing. (lol)

App Screenshot

Flow of App Run:

  1. Start the app
  2. MainActivity is shown.
  3. Start 'Settings' app from command line.
  4. Press back to exit from the Settings, back to the Lifecycles app
  5. Press back to exit from the app.
          LifeCyclesApp  D  onCreate()
           MainActivity  D  onCreate()
                         D  onStart()
                         D  onResume()
...
                         D  onPause()
    Process com.android.settings created for activity com.android.settings/.Settings
           MainActivity  D  onStop()
...           
                         D  onStart()
                         D  onResume()
...                         
                         D  onPause()
                         D  onStop()
                         D  onDestroy()

Yes by looking at the logs it makes lot of sense. But wait, What happened to onTerminate() method of LifeCyclesApp class? It didn't appear in the logs. I did exit from the app. May be if I wait for a while, android kills the app after a while.

Waiting...

Nope.

onTerminate() wasn't called yet.

How about take one more step to ensure that app is stopped? I went to Settings->Applications and tried to 'Force Stop' the app.

Nah!. onTerminate() was never called.

I looked into the javadoc documentation of onTerminate() method and found out that's true.

public class Application extends ContextWrapper ... {
    ...

    /**
     * This method is for use in emulated process environments.  It will
     * never be called on a production Android device, where processes are
     * removed by simply killing them; no user code (including this callback)
     * is executed when doing so.
     */
    @CallSuper
    public void onTerminate() {
    }
    ...
}

I verified the above statement as well.

1|root@xxx:/ # ps | grep life                                                 
u0_a46    9368  2243  878808 26364 ffffffff 401de834 S com.chaturaloka.lifecycles
root@xxx:/ # kill 9368
          LifeCyclesApp  D  onCreate()
           MainActivity  D  onCreate()
                         D  onStart()
                         D  onResume()

        Process com.chaturaloka.lifecycles (PID: 9368) ended

Even killing the app process didn't call the onTerminate() method. However it was interesting to see onStop() and onDestroy() methods of MainActivity were not invoked as well when killing the app process. However If you pay little more attention to the android activity life-cycles diagram, this is the expected behavior of the activity.

Probably you are thinking, I could have checked the documentation in the first place. Yeah! I agree. However I was happy that I learnt the life-cycles theoratically as well as practically.

Now on to the next adventure of Single Activity with one Fragment!!

This post is also available on DEV.

All rights reserved