Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package io.github.chayanforyou.asynctask
- import kotlinx.coroutines.*
- const val TAG = "ASYNCTASK"
- /**
- * A replacement for the traditional Android `AsyncTask`, leveraging Kotlin coroutines for improved
- * readability and performance. This class simplifies asynchronous operations, providing hooks for
- * various stages of the task lifecycle.
- *
- * @param Params The type of the input parameters.
- * @param Progress The type of the progress units published during the background computation.
- * @param Result The type of the result of the background computation.
- */
- class AsyncTask<Params, Progress, Result> {
- private var job: Job? = null
- private var onPreExecute: (() -> Unit)? = null
- private var doInBackground: (suspend BackgroundTaskScope.(params: List<Params>) -> Result)? = null
- private var onProgressUpdate: ((progress: Progress) -> Unit)? = null
- private var onPostExecute: ((result: Result) -> Unit)? = null
- private var onCancelled: (() -> Unit)? = null
- private var onError: ((Throwable) -> Unit)? = null
- /**
- * Sets a callback to be invoked on main thread before the task is executed.
- *
- * @param callback A lambda function to be executed before the task starts.
- * @return The current instance of [AsyncTask] to allow for method chaining.
- */
- fun onPreExecute(callback: () -> Unit): AsyncTask<Params, Progress, Result> {
- onPreExecute = callback
- return this
- }
- /**
- * Sets the background computation to be executed on a background thread.
- *
- * @param callback A suspending lambda function to be executed in the background.
- * @return The current instance of [AsyncTask] to allow for method chaining.
- */
- fun doInBackground(callback: suspend BackgroundTaskScope.(params: List<Params>) -> Result): AsyncTask<Params, Progress, Result> {
- doInBackground = callback
- return this
- }
- /**
- * Sets a callback to be invoked on main thread when progress is updated.
- *
- * @param callback A lambda function to be executed on the main thread to update the progress.
- * @return The current instance of [AsyncTask] to allow for method chaining.
- */
- fun onProgressUpdate(callback: (progress: Progress) -> Unit): AsyncTask<Params, Progress, Result> {
- onProgressUpdate = callback
- return this
- }
- /**
- * Sets a callback to be invoked on main thread after the background computation finishes.
- *
- * @param callback A lambda function to be executed on the main thread with the result of the computation.
- * @return The current instance of [AsyncTask] to allow for method chaining.
- */
- fun onPostExecute(callback: (result: Result) -> Unit): AsyncTask<Params, Progress, Result> {
- onPostExecute = callback
- return this
- }
- /**
- * Sets a callback to be invoked if the task is cancelled.
- *
- * @param callback A lambda function to be executed on the main thread if the task is cancelled.
- * @return The current instance of [AsyncTask] to allow for method chaining.
- */
- fun onCancelled(callback: () -> Unit): AsyncTask<Params, Progress, Result> {
- onCancelled = callback
- return this
- }
- /**
- * Sets a callback to be invoked if an error occurs during the background computation.
- *
- * @param callback A lambda function to be executed on the main thread if an error occurs.
- * @return The current instance of [AsyncTask] to allow for method chaining.
- */
- fun onError(callback: (Throwable) -> Unit): AsyncTask<Params, Progress, Result> {
- onError = callback
- return this
- }
- /**
- * Executes the task with the provided parameters.
- *
- * @param params The parameters of the task.
- */
- fun execute(params: List<Params> = emptyList()) {
- job = CoroutineScope(Dispatchers.Main).launch {
- try {
- onPreExecute?.invoke()
- val result = withContext(Dispatchers.IO) {
- doInBackground?.let { it(BackgroundTaskScope(), params) }
- }
- result?.let { onPostExecute?.invoke(it) }
- } catch (e: Throwable) {
- onError?.invoke(e)
- }
- }
- }
- /**
- * Publishes progress updates to the main thread.
- *
- * @param progress The progress value to be published.
- */
- fun publishProgress(progress: Progress) {
- CoroutineScope(Dispatchers.Main).launch {
- onProgressUpdate?.invoke(progress)
- }
- }
- /**
- * Cancels the task if it is currently running.
- */
- fun cancel() {
- job?.cancel()
- onCancelled?.invoke()
- }
- /**
- * Scope for the background task, allowing for progress updates.
- */
- inner class BackgroundTaskScope {
- /**
- * Publishes progress updates to the main thread.
- *
- * @param progress The progress value to be published.
- */
- fun publishProgress(progress: Progress) {
- this@AsyncTask.publishProgress(progress)
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement