Is there a way to pass a function reference between activities?

2022 Update:

  1. 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.
  2. Actually there is another API just for listening changes from one Fragment in the other, that is FragmentResultListener, offical tutorial is here: https://youtu.be/oP-zXjkT0C0?t=468.
  3. 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 Fragments): 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.

Tags:

Android

Kotlin