Create generic higher order function in kotlin

Astha Garg

I have an interface GalleryImagesDataCallback which I use to pass data from background thread to UI thread, to avoid calling runOnUiThread() from each overriden method of GalleryImagesDataCallback, I have used kotlin higher order function.

interface GalleryImagesDataCallback {

fun fetchedList(list: ArrayList<ImageGalleryItemModel>)

@JvmDefault
fun callMethodOnUIThreadForFetch(mContext: Context, list:ArrayList<ImageGalleryItemModel>,func: (ArrayList<ImageGalleryItemModel>) -> Unit) {
   (mContext as BaseActivity).runOnUiThread {
     Logger.error("TEST_ABC","callMethodOnUIThreadForFetch Enter")
     func(list)
   }
}

fun deleteList()

@JvmDefault
fun callMethodOnUIThreadForDelete(mContext: Context, func: () -> Unit) {
(mContext as BaseActivity).runOnUiThread {
   Logger.error("TEST_ABC","callMethodOnUIThreadForDelete Enter")
   func()
 } 
}    

}

Calling from background thread:

callback.callMethodOnUIThreadForFetch(mContext,list) {list:ArrayList<ImageGalleryItemModel> -> callback.fetchedList(list)}  // callback is reference of GalleryImagesDataCallback

callback.callMethodOnUIThreadForDelete(mContext) {callback.deleteList()}

Problem :

Right now I'm having 2 separate methods callMethodOnUIThreadForDelete() and callMethodOnUIThreadForFetch(). Is there any way in kotlin to create one generic method (say callMethodOnUIThread()) which I can use to call deleteList() and fetchedList() both with no change in function definition?

Tenfour04

First to answer your literal question, your callMethodOnUIThreadForFetch function has unnecessary redirection of the list argument. Why make the list an argument of the higher-order function only to pass it right back to the function argument? You could use your callMethodOnUIThreadForDelete function for either purpose, but suppose we rename it and remove the unsafe cast to Activity by using a Handler:

// In interface:
fun callMethodOnUIThread(context: Context, func: () -> Unit) {
    Handler(context.mainLooper).post(func)
}

// From background thread:
callback.callMethodOnUIThread(mContext) { callback.fetchedList(list) }
callback.callMethodOnUIThread(mContext) { callback.deleteList() }

Assuming that you want to simplify the work of implementing this interface, then I don't think this actually helps. You've pushed the work of calling code on the UI thread from the interface implementation into the user of the interface. You may as well create a global helper function, instead of cluttering your interface, which is a weird place for it. Usage becomes more straightforward:

// Global utility function, not in a class
fun Context.onUiThread(func: () -> Unit) {
    Handler(mainLooper).post(func)
}

// Usage:
mContext.onUiThread { callback.fetchedList(list) }
mContext.onUiThread { callback.deleteList() }

If you really want to fully encapsulate the thread switching, you would have to change your interface into an abstract class like this:

abstract class GalleryImagesDataCallback {
    protected abstract fun fetchedListImpl(list: List<String>)
    protected abstract fun deleteListImpl()

    fun fetchedList(context: Context, list: List<String>) {
        Handler(context.mainLooper).post { fetchListImpl(list) }
    }

    fun deleteList(context: Context) {
        Handler(context.mainLooper).post { deleteListImpl() }
    }
}

So instead of implementing the interface, you would create subclasses of this and implement the two abstract functions. Neither the subclass or the user of the callback has to be concerned with ensuring code is called on the UI thread.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Kotlin Higher Order Function Composition

Kotlin: higher order function with recursion

Kotlin Higher Order Function in ViewModel

Higher order (or recursive?) generic type parameters in kotlin

Higher-order function returning generic function

Kotlin higher order function for passing a function to a map

noImplicitAny does not work on generic higher order function

typescript generic type inference in higher order function

Generic higher order function parameter type

Typescript: How to type generic higher order function

Kotlin higher order function parameters: Passing subtypes

Is it possible to map a higher order function in kotlin to a string

Call Higher Order function of Kotlin from Java

TypeScript default function for higher-order function generic type

How to create a Generic Function in Kotlin

Generic, higher order functions

Kotlin Higher Order Function pass a function with variable number of arguments as the parameter

Build generic reusable iteration module from higher order function

Incompatible flow-type for generic higher order function

Calling a Kotlin higher-order function from Java

References to variables aren't supported yet in Kotlin higher order function

kotlin: call higher-order function with multiple lambdas

How to use Kotlin Higher Order Function in nested Recyler View

Wrap a function in try catch using Higher order functions in Kotlin

How to create higher order function in react functional component

Higher order filter function

Higher Order Function in Swift

Higher order function parameter

Higher order function in BindingAdapter