Karl Einstein
Karl Einstein

Reputation: 75

Android AsyncTask is not updating Progress Bar

Hello I have a problem with asynctask.I play a song then I update duration to progressbar. But when I play a new song progressbar don't back to 0th position and progressbar is continuing with old value Here is my code:

class Task(context: Context, progressBar: ProgressBar) : AsyncTask<Int, Int, String>() {
@SuppressLint("StaticFieldLeak")
private var progressBar: ProgressBar? = progressBar
private var count = 0
override fun doInBackground(vararg input: Int?): String {
    while (count <= input[0]!!) {
        count++
        publishProgress(count)
        Thread.sleep(1000)
        if (isCancelled){
            count=0
        }
    }
    return "Task completed"
}

override fun onPreExecute() {
    progressBar!!.progress = 0
}

override fun onProgressUpdate(vararg values: Int?) {
    progressBar!!.progress = values[0]!!
}
}

when I play song :

    override fun onItemClicked(position: Int, song: Song) {
    val secondsDuration = song.duration!! / 1000
    activity!!.pgbSong.max = secondsDuration
    val task = Task(context!!, activity!!.pgbSong)
    if (task.status == AsyncTask.Status.RUNNING) {
        task.cancel(true)
    }
    task.execute(song.duration)
}

Upvotes: 1

Views: 565

Answers (1)

Demigod
Demigod

Reputation: 5635

Well, what to say - you never cancel previous async tasks. Cause you're calling cancel(true) on just created async tasks every time:

val task = Task(context!!, activity!!.pgbSong)
if (task.status == AsyncTask.Status.RUNNING) {
    task.cancel(true)
}
task.execute(song.duration)

Instead, you should save previous async task in an object variable (something like this):

private var asyncTask : AsyncTask<*,*,*>? = null

And after in the method call:

override fun onItemClicked(position: Int, song: Song) {
    if (asyncTask.status == AsyncTask.Status.RUNNING) {
        asyncTask.cancel(true)
    }

    val secondsDuration = song.duration!! / 1000
    activity!!.pgbSong.max = secondsDuration
    asyncTask = Task(context!!, activity!!.pgbSong)
    asyncTask.execute(song.duration)
}

And, I guess, you should do a return in an AsyncTask when you're checking if it canceled or not.

But please don't use AsyncTask in this manner. Cause it holds links views and activity which can prevent those of being garbage collected and so cause a memory leak.

And please don't use !! with Kotlin. Instead use null check or provide default value if null. Examples:

val int = object?.int ?: 0
val context = activity ?: return
val view = activity?.pgbSong ?: return // or if (view != null)

Upvotes: 2

Related Questions