Activities in Android Development

Dive Deep into Activity Lifecycle, Navigation, and Best Practices with Kotlin Examples

Activities in Android Development

Activities are one of the fundamental building blocks of Android applications. They represent a single screen with a user interface and play a critical role in managing user interaction in an app. If you're new to Android development or want to deepen your understanding of Activities, this blog will walk you through everything you need to know.


What is an Activity?

An Activity in Android is a component that provides a screen where users can interact with the app. It acts as an entry point for the user to perform actions such as viewing a form, scrolling through a list, or playing a game.

Each Activity is a descendant of the Activity class in the Android framework. Activities often work together to provide a cohesive user experience, transitioning from one Activity to another via Intents.


Key Features of Activities

  1. Lifecycle Management
    Android Activities have a well-defined lifecycle managed by the system. This ensures efficient use of resources, especially in memory-constrained environments.

  2. UI Rendering
    Each Activity is responsible for rendering a portion of the app’s UI using an XML layout or programmatically created views.

  3. Inter-Activity Communication
    Activities can communicate with each other and pass data using Intents and Bundles.


Activity Lifecycle

The Activity lifecycle defines how an Activity transitions between different states:

  1. onCreate()
    Called when the Activity is created. Initialize views, set up bindings, and prepare resources here.

  2. onStart()
    Called when the Activity becomes visible to the user.

  3. onResume()
    Called when the Activity starts interacting with the user. The app is now in the foreground.

  4. onPause()
    Called when the Activity is partially obscured (e.g., when a dialog appears or the user switches apps). Use this to pause ongoing tasks.

  5. onStop()
    Called when the Activity is no longer visible. Release resources not needed when the Activity is not visible.

  6. onDestroy()
    Called when the Activity is being destroyed either by the system or explicitly by the developer.

  7. onRestart()
    Called after the Activity has been stopped, just before restarting.

Logging Activity Lifecycle

You can log the Activity lifecycle states in the console by overriding each lifecycle callback method in your Activity and using the Log class.

Here's how to implement it in Kotlin:

Code Example: Logging the Activity Lifecycle

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    // Tag for logging
    private val TAG = "MainActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d(TAG, "onCreate called")
    }

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

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

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

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

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

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

Explanation of the Code

  1. Logging the Lifecycle Methods
    Each overridden method logs a message indicating when it is called. The Log.d() method is used for debug-level logging, and the tag (TAG) helps identify logs specific to this Activity.

  2. Tagging Logs
    Using a consistent tag (MainActivity) allows you to filter and identify logs easily in the Logcat.

  3. Lifecycle States Covered

    • onCreate()

    • onStart()

    • onResume()

    • onPause()

    • onStop()

    • onDestroy()

    • onRestart()

  4. Logcat Output
    When you run the app and interact with the Activity (e.g., switch between apps or rotate the screen), the lifecycle logs will appear in the Logcat:

     D/MainActivity: onCreate called
     D/MainActivity: onStart called
     D/MainActivity: onResume called
     D/MainActivity: onPause called
     D/MainActivity: onStop called
     D/MainActivity: onDestroy called
    

Testing the Lifecycle Logs

  1. Open the Logcat
    In Android Studio, open Logcat from the bottom panel to see real-time logs.

  2. Perform Actions

    • Open the app (triggers onCreate, onStart, and onResume).

    • Minimize the app (triggers onPause and onStop).

    • Reopen the app (triggers onRestart, onStart, and onResume).

    • Close the app (triggers onDestroy).

  3. Filter Logs
    Use the filter option in Logcat to display logs with the tag "MainActivity".


By implementing this logging mechanism, you can observe the transitions between lifecycle states and better understand how your Activity behaves during user interactions or configuration changes.

Diagrammatically, the lifecycle can be represented as:


Creating an Activity

To create an Activity in an Android app:

  1. Define the Activity Class
    Create a new class that extends Activity or AppCompatActivity:

     public class MainActivity extends AppCompatActivity {
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
         }
     }
    
  2. Define the Layout
    Specify the user interface in an XML file (e.g., activity_main.xml):

     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical">
    
         <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Welcome to MainActivity!" />
     </LinearLayout>
    
  3. Register the Activity in AndroidManifest.xml
    Declare the Activity in the AndroidManifest.xml file:

     <activity android:name=".MainActivity">
         <intent-filter>
             <action android:name="android.intent.action.MAIN" />
             <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
     </activity>
    

Navigating Between Activities

Use Intents to navigate from one Activity to another:

  1. Explicit Intent
    When you know the target Activity, use an explicit Intent:

     Intent intent = new Intent(this, SecondActivity.class);
     startActivity(intent);
    
  2. Passing Data Between Activities
    Add extra data to the Intent using key-value pairs:

     Intent intent = new Intent(this, SecondActivity.class);
     intent.putExtra("USERNAME", "John Doe");
     startActivity(intent);
    

    Retrieve the data in the target Activity:

     String username = getIntent().getStringExtra("USERNAME");
    

Types of Activities

  1. Launcher Activity
    The main entry point of an app, specified in the AndroidManifest.xml.

  2. Dialog Activity
    An Activity with a dialog-like appearance, achieved by customizing the theme.

  3. Full-Screen Activity
    Often used for immersive experiences like games, hiding the status bar and navigation bar.

  4. Transparent Activity
    Useful for overlays, achieved using transparent themes.


Best Practices for Working with Activities

  1. Minimize Work in onCreate()
    Avoid heavy operations in onCreate() to ensure quick loading of the Activity.

  2. Optimize State Management
    Save and restore state during lifecycle transitions using onSaveInstanceState() and onRestoreInstanceState().

  3. Reuse Fragments
    Use Fragments for modular and reusable UI components, especially in multi-pane layouts.

  4. Follow Material Design Guidelines
    Ensure your Activity UI aligns with Google’s Material Design for a consistent user experience.

  5. Handle Configuration Changes
    Handle screen rotations and other configuration changes effectively by using ViewModel or onConfigurationChanged().


Common Use Cases

  1. Form Input
    Use an Activity for user input, such as login forms or settings pages.

  2. Lists and Details
    Use one Activity for a list view and another for detailed views.

  3. Splash Screens
    Implement a splash screen Activity to display branding or loading animations.

  4. Authentication Flows
    Create a sequence of Activities to guide users through login and registration processes.


Conclusion

Activities are at the heart of Android app development, providing the framework for user interaction. Understanding their lifecycle, usage patterns, and best practices is essential for building efficient, responsive, and user-friendly apps. By mastering Activities, you lay the groundwork for creating robust Android applications that stand out in terms of functionality and design.