Is there a way to pass a function reference between activities?
2022 Update:
- My original approach has a drawback, in my demo if I press the home button to put the app into the background, it will crash with
NotSerializableException
. - Actually there is another API just for listening changes from one
Fragment
in the other, that isFragmentResultListener
, offical tutorial is here: https://youtu.be/oP-zXjkT0C0?t=468. - If
FragmentResultListener
cannot meet your need,Shared ViewModel
is the final solution in there: https://youtu.be/THt9QISnIMQ.
1. You need to add id 'kotlin-parcelize'
to your build.gradle (app), like this:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'kotlin-parcelize' //here
}
2. Create a Class to wrap your Lambda function:
@Parcelize
class Listener(val clickAction: () -> Unit) : Parcelable {
fun onClick() = clickAction()
}
3. Pass your Lambda:
val bundle = Bundle().apply {
putParcelable("listener", Listener(clickAction))
}
private val clickAction: () -> Unit = {
//do your stuff
}
4. Retrieve it:
arguments?.getParcelable<Listener>("listener")?.onClick()
Demo (all Fragment
s): https://youtu.be/0OnaW4ZCnbk
If tryAgainFunction
is Serializable
, then you can put it into the bundle
using bundle.putSerializable("try_again_function", tryAgainFunction);
.
It will actually be Serializable
if it is a function reference (SomeClass::someFunction
) or a lambda. But it might not be, if it is some custom implementation of the functional interface () -> Unit
, so you should check that and handle the cases when it's not.