Android Development
OnActivityResult
Deprecated Methods
Activity Result API
Coding Alternatives

OnActivityResult method is deprecated, what is the alternative?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In Android development, handling the results of activities has traditionally been done using the onActivityResult method. However, this method is now deprecated, and developers are encouraged to use the new Activity Result APIs. This article will provide an in-depth look at why onActivityResult has been deprecated, and how to implement the new Activity Result APIs effectively.

The Deprecation of onActivityResult

Background

The onActivityResult method has been a staple in Android development for communicating between activities and fragments. It allows a source activity to start a target activity and receive a result back from it. However, this approach has several drawbacks:

  1. Tight Coupling: The method necessitates callback handling within the Activity or Fragment, which can lead to tight coupling.
  2. Complexity: Managing request and result codes becomes cumbersome as the app scales, making the codebase harder to maintain.
  3. Lifecycle Sensitivity: The method is sensitive to lifecycle changes—developers often have to manage complex state-saving logic to handle configuration changes or process death.

Due to these limitations, the Activity Result APIs were introduced to offer a more robust and modular solution.

Introducing: Activity Result APIs

The new Activity Result APIs provide a type-safe and lifecycle-aware approach to handle activity results. Here’s how the new API improves upon the deprecated method:

  1. Decoupling: Activities and Fragments handle results in a decoupled manner, avoiding bloated callback methods.
  2. Lifecycle Awareness: Results are delivered only when lifecycle conditions are safe, leveraging Jetpack’s lifecycle components.
  3. Simplified Code: It eliminates the need for custom request/result codes and reduces boilerplate code.

Implementation

1. Setting Up Dependencies

Ensure you have the necessary dependencies in your build.gradle file:

groovy
1dependencies {
2    implementation "androidx.activity:activity-ktx:1.2.3"
3    implementation "androidx.fragment:fragment-ktx:1.3.4"
4}

2. Registering for Activity Result

The new API uses ActivityResultLauncher to handle the results. You register this in the component (Activity or Fragment) using a registerForActivityResult call.

Example in a MainActivity:

kotlin
1class MainActivity : AppCompatActivity() {
2
3    private lateinit var getContent: ActivityResultLauncher<String>
4
5    override fun onCreate(savedInstanceState: Bundle?) {
6        super.onCreate(savedInstanceState)
7        setContentView(R.layout.activity_main)
8
9        getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
10            // Handle the returned URI
11            uri?.let {
12                // Do something with the URI, e.g., display it in an ImageView
13            }
14        }
15
16        findViewById<Button>(R.id.button).setOnClickListener {
17            // Trigger the activity to get an image
18            getContent.launch("image/*")
19        }
20    }
21}

3. Launching the Activity

Using this method, launching the activity is more explicit, focusing on the action (such as fetching content) rather than managing codes.

Key Benefits and Comparison

Below is a table summarizing the key differences between onActivityResult and the new Activity Result APIs:

FeatureonActivityResultActivity Result APIs
CouplingTight coupling through callbacksDecoupled via ActivityResultLauncher
Code ComplexityHigh due to request code managementLow; uses type-safe contracts
Lifecycle ManagementDeveloper-managedBuilt-in lifecycle awareness
Error HandlingManual error checkingSimplified, with reduced boilerplate
ReusabilityLimitedHighly reusable and modular

Additional Details

Handling Permissions

The new Activity Result APIs also extend to handling permissions more gracefully. For instance, instead of using the old requestPermissions method, you now use ActivityResultContracts.RequestPermission:

kotlin
1private val requestPermissionLauncher =
2    registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
3        if (isGranted) {
4            // Permission is granted
5        } else {
6            // Permission is denied
7        }
8    }
9
10private fun requestCameraPermission() {
11    requestPermissionLauncher.launch(Manifest.permission.CAMERA)
12}

Custom Activity Result Contracts

The ActivityResultContracts class provides a set of predefined contracts, but you can also define custom contracts for complex operations. Here's a simple example:

kotlin
1class CustomContract : ActivityResultContract<InputType, OutputType>() {
2    override fun createIntent(context: Context, input: InputType): Intent {
3        // Return an Intent for use with startActivityForResult
4    }
5
6    override fun parseResult(resultCode: Int, intent: Intent?): OutputType {
7        // Parse the return data from the activity result
8    }
9}

Conclusion

The deprecation of onActivityResult is part of Android’s effort to encourage cleaner, more maintainable code through modern APIs. The new Activity Result APIs offer significant improvements in terms of decoupling, lifecycle awareness, and code simplicity. By leveraging these APIs, developers can ensure their applications are robust, modular, and aligned with the latest best practices in Android development.


Course illustration
Course illustration

All Rights Reserved.