The story about startActivityForResult in Android

Tuan Kiet
2 min readAug 3, 2020

--

At this time you all probably heard about the new API to get the result from an Activity. In a nutshell, they look something like this:

val getContent = registerForActivityResult(GetContent()) {
// Handle the returned Uri
}

override fun onCreate(savedInstanceState: Bundle?) {
// ...
selectButton.setOnClickListener {
getContent.launch("image/*")
}
}

They change from hooking into onActivityResult to a more elegant callback style. And as always, it comes with some gotcha as mentioned here.

If you use the Navigation Component and want to get a result from another Fragment, then good luck, because you have to do some crazy stuff like:

findNavController().currentBackStackEntry
?.savedStateHandle?.set("a", "b")
findNavController().previousBackStackEntry
?.savedStateHandle
?.getLiveData<String>("a")
?.observe(viewLifecycleOwner) {
// handle the result
}

And it with some gotcha as usual.

At this point, a thought comes through my mind: “Heck, why so complicated” and decide to solve this problem my way. The way that is simple, easy to use, and doesn't get deprecated in a few years.

After some experiment, I come up with something called ResultManager

The basic idea is every time you want to get a result from Activity/Fragment. First, generate a request code (a UUID will do), call getResult immediately (best to put the call inside ViewModel). Then launch the Activity/Fragment with the request code as a parameter.

When you want to send back the result, just call sendResult

You don’t need to call cancel, everything will still work because of the call resultManager.getResult get suspended until someone sent back the result until then nothing will happen, inside onClear the viewModelScope got canceled so that the request coroutine got canceled too.

And just like that, you have a simple homemade solution to deal with the “result” problem. The best thing about this approach:

  • The ResultManager the platform-neutral, so you can do flexible stuff like an Activity request result from a Fragment, a View, or literally anything. You can also request a result, then send the result back from 2–3 aways in the navigation stack, as long as you have the request code, you are good to go.
  • The Result’s type can be anything, not limited to Serialiable or Parcelable

Never deprecated : )

--

--