LCZ
LCZ

Reputation: 729

How do I ensure a function runs once at a given time, and not concurrently?

I have a function function(). How can I ensure, when the function is called multiple times, that it would run one after another, and not concurrently? I am using Kotlin 1.3 in Android Studio 3.5.

My code is

 button.setOnClickListener{function()}

The problem is, the button can be pressed multiple times while the function() is still running, hence I want the subsequent invocations of function() to be executed sequentially, one after another, instead of at the same time.

EDIT: My function definition is

fun function(){
    image.animate().rotationBy(360F).setDuration(500)
}

The user could press the button more than once, hence the result is that the image(image) gets rotated to an angle, as the image is being rotated again while it did not complete the full rotation, ending up being rotated at another angle instead of 0°.

Upvotes: 3

Views: 3610

Answers (4)

Mousa
Mousa

Reputation: 2290

The @Synchronized annotation does exactly what you want:

@Synchronized
private fun function() {
    //...
}

Upvotes: 1

Simon
Simon

Reputation: 1737

I'd suggest WorkManager (especially if the function is some long running async job) to enqueue a job.

  1. Add it to gradle:
implementation "androidx.work:work-runtime-ktx:2.2.0"
  1. Create the class containing your method (function)
class Task(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {

    override fun doWork(): Result {
        //Call the function
        return Result.success()
    }
}
  1. Create a job with parameters:
val uploadWorkRequest = OneTimeWorkRequestBuilder<Task>()
.build()
  1. Enqueue the job on button click:
WorkManager.getInstance(myContext).enqueue(uploadWorkRequest)

Upvotes: 0

Jaswant Singh
Jaswant Singh

Reputation: 10761

Take a Boolean as hasRan = false

And when you call the function, check if the hasRan is false, and at the end of the function set hasRan = true, execute the function only if the value of hasRan is false.

This way the function will only run once.

Upvotes: 0

Sushant Somani
Sushant Somani

Reputation: 1500

You can call this function only from an IntentService. The IntentService offloads task from the main thread and runs them over a Worker Thread. The tasks in Worker Thread are executed sequentially.

class SampleIntentService(): IntentService("SampleIntentService") {
override fun onHandleIntent(intent: Intent?) {
//TODO call function() here
 }
}

You can start this service using startService() method.

Upvotes: -1

Related Questions