Android kills low priority apps  you haven’t used in a while, thanks to a phenomenon called garbage collection.

Your app is not in control of it’s own destiny, it can be killed at anytime which means you need to know how to deal with such scenario which means understanding the lifecycle of an activity we get from the android framework to indicate progress through the lifetime.

Some Android Lifecycle Methods

OnCreate

This is where views are created and should be initialised

onStart

Indicates that the activity has becomes visible

onStart

This is when the activity is actively running in the foreground (what’s on your screen) and has focus.

onPause

Indicates that an activity has lost focus or is partially obscured. Such as when a dialog is launched or when an app needs to fulfil an implicit intent or when using split screen (Nougat, 7.0 + )

OnStop

Indicates that the app is no longer visible or completely obscured and is running in the background

onDestroy

Indicates the end of the app lifecycle

Saving and Restoring Instance State

When configuration change such as screen rotation occurs initiated values (integer, string, boolean, byte, long etc list of supported values) will be lost because the previous activity has been destroyed and a new one created

Thankfully android has a way of letting us keep such values without hassle.

onSavedInstanceState and onRestoreInstanceState are used to save and restore values respectively.

onSavedInstanceState provides a bundle outState which can be used to store a key-value pair like any other bundle. Also onRestoreInstanceState provides a bundle savedInstanceState which can be used to get stored key-value pair. savedInstanceState throws a nullPointerException when intent bundle is empty, therefore, always check for nullity, before calling getIntent() to access any value.

Useful Tips

  1. Always attach your listeners and any other resource consuming object in onResume and detach them in onPause. This is done in order to avoid Memory Leaks.
  2. Pause and Resume your adView Banner ad in onPause and onResume methods respectively. This is done in order to stop a re-load of adRequest whenever there’s a configuration change(such as screen rotation), hence maximise ad revenue and increase app efficiency.
  3. Never put an important or long piece of code in onDestroy. It has a reputation of not executing all its code.
    For example committing to a shared preferences or a database should be done in onStop.
    There’s not a guarantee that onDestroy() will be called, and in some cases processes such as your app will be killed (such as when user uses a memory cleaning app) directly, bypassing the method call anyway.
    Use onDestroy to destroy references to memory consuming objects for example mAdView?.destroy() or mBillingManager?.destroyBillingClient()

Basic Example

[button color=”green” size=”medium” link=”https://github.com/Edge-Developer/AndroidLifecycleTutorial” icon=”” target=”false”]Grab Source Code on Github[/button]

1. activity_main.xml

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="`Launch Share Dialog"
        android:onClick="click"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

2. MainActivity.kt

class MainActivity : AppCompatActivity() {
    val TAG = "MainActivity"
    var text = "Empty!"
    val TEXT_KEY = "text.key"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        Log.d(TAG, "onCreate")
        Log.d(TAG, text)

        text = "This Text is no longer empty, it has been preserved by onSavedInstanceState"
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        super.onRestoreInstanceState(savedInstanceState)
        Log.d(TAG, "onRestoreInstanceState")
        if (savedInstanceState != null) {
            text = intent.getStringExtra(TEXT_KEY)
            Log.d(TAG, "onRestoreInstanceState. text = $text")
        }
    }

    override fun onStart() {
        super.onStart()
        Log.d(TAG, "onStart")
    }
    override fun onResume() {
        super.onResume()
        Log.d(TAG, "onResume")
    }

    override fun onRestart() {
        super.onRestart()
        Log.d(TAG, "onRestart")
    }

    override fun onPause() {
        super.onPause()
        Log.d(TAG, "onPause")
    }

    override fun onStop() {
        super.onStop()
        Log.d(TAG, "onStop")
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        Log.d(TAG, "onSaveInstanceState")
        outState?.putString(TEXT_KEY, text)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy")
    }

    fun click(view: View){
        ShareCompat.IntentBuilder.from(this)
                .setType("text/plain")
                .setSubject(getString(R.string.app_name))
                .setText("Some Freaky Text")
                .startChooser()
        Log.d(TAG, "Showed a Share Dialog")
    }
}

 

Leave a comment