Advertisement
chayanforyou

AsyncTask

Jul 1st, 2024
1,059
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 5.14 KB | None | 0 0
  1. package io.github.chayanforyou.asynctask
  2.  
  3. import kotlinx.coroutines.*
  4.  
  5. const val TAG = "ASYNCTASK"
  6.  
  7. /**
  8.  * A replacement for the traditional Android `AsyncTask`, leveraging Kotlin coroutines for improved
  9.  * readability and performance. This class simplifies asynchronous operations, providing hooks for
  10.  * various stages of the task lifecycle.
  11.  *
  12.  * @param Params The type of the input parameters.
  13.  * @param Progress The type of the progress units published during the background computation.
  14.  * @param Result The type of the result of the background computation.
  15.  */
  16. class AsyncTask<Params, Progress, Result> {
  17.  
  18.     private var job: Job? = null
  19.     private var onPreExecute: (() -> Unit)? = null
  20.     private var doInBackground: (suspend BackgroundTaskScope.(params: List<Params>) -> Result)? = null
  21.     private var onProgressUpdate: ((progress: Progress) -> Unit)? = null
  22.     private var onPostExecute: ((result: Result) -> Unit)? = null
  23.     private var onCancelled: (() -> Unit)? = null
  24.     private var onError: ((Throwable) -> Unit)? = null
  25.  
  26.     /**
  27.      * Sets a callback to be invoked on main thread before the task is executed.
  28.      *
  29.      * @param callback A lambda function to be executed before the task starts.
  30.      * @return The current instance of [AsyncTask] to allow for method chaining.
  31.      */
  32.     fun onPreExecute(callback: () -> Unit): AsyncTask<Params, Progress, Result> {
  33.         onPreExecute = callback
  34.         return this
  35.     }
  36.  
  37.     /**
  38.      * Sets the background computation to be executed on a background thread.
  39.      *
  40.      * @param callback A suspending lambda function to be executed in the background.
  41.      * @return The current instance of [AsyncTask] to allow for method chaining.
  42.      */
  43.     fun doInBackground(callback: suspend BackgroundTaskScope.(params: List<Params>) -> Result): AsyncTask<Params, Progress, Result> {
  44.         doInBackground = callback
  45.         return this
  46.     }
  47.  
  48.     /**
  49.      * Sets a callback to be invoked on main thread when progress is updated.
  50.      *
  51.      * @param callback A lambda function to be executed on the main thread to update the progress.
  52.      * @return The current instance of [AsyncTask] to allow for method chaining.
  53.      */
  54.     fun onProgressUpdate(callback: (progress: Progress) -> Unit): AsyncTask<Params, Progress, Result> {
  55.         onProgressUpdate = callback
  56.         return this
  57.     }
  58.  
  59.     /**
  60.      * Sets a callback to be invoked on main thread after the background computation finishes.
  61.      *
  62.      * @param callback A lambda function to be executed on the main thread with the result of the computation.
  63.      * @return The current instance of [AsyncTask] to allow for method chaining.
  64.      */
  65.     fun onPostExecute(callback: (result: Result) -> Unit): AsyncTask<Params, Progress, Result> {
  66.         onPostExecute = callback
  67.         return this
  68.     }
  69.  
  70.     /**
  71.      * Sets a callback to be invoked if the task is cancelled.
  72.      *
  73.      * @param callback A lambda function to be executed on the main thread if the task is cancelled.
  74.      * @return The current instance of [AsyncTask] to allow for method chaining.
  75.      */
  76.     fun onCancelled(callback: () -> Unit): AsyncTask<Params, Progress, Result> {
  77.         onCancelled = callback
  78.         return this
  79.     }
  80.  
  81.     /**
  82.      * Sets a callback to be invoked if an error occurs during the background computation.
  83.      *
  84.      * @param callback A lambda function to be executed on the main thread if an error occurs.
  85.      * @return The current instance of [AsyncTask] to allow for method chaining.
  86.      */
  87.     fun onError(callback: (Throwable) -> Unit): AsyncTask<Params, Progress, Result> {
  88.         onError = callback
  89.         return this
  90.     }
  91.  
  92.     /**
  93.      * Executes the task with the provided parameters.
  94.      *
  95.      * @param params The parameters of the task.
  96.      */
  97.     fun execute(params: List<Params> = emptyList()) {
  98.         job = CoroutineScope(Dispatchers.Main).launch {
  99.             try {
  100.                 onPreExecute?.invoke()
  101.                 val result = withContext(Dispatchers.IO) {
  102.                     doInBackground?.let { it(BackgroundTaskScope(), params) }
  103.                 }
  104.                 result?.let { onPostExecute?.invoke(it) }
  105.             } catch (e: Throwable) {
  106.                 onError?.invoke(e)
  107.             }
  108.         }
  109.     }
  110.  
  111.     /**
  112.      * Publishes progress updates to the main thread.
  113.      *
  114.      * @param progress The progress value to be published.
  115.      */
  116.     fun publishProgress(progress: Progress) {
  117.         CoroutineScope(Dispatchers.Main).launch {
  118.             onProgressUpdate?.invoke(progress)
  119.         }
  120.     }
  121.  
  122.     /**
  123.      * Cancels the task if it is currently running.
  124.      */
  125.     fun cancel() {
  126.         job?.cancel()
  127.         onCancelled?.invoke()
  128.     }
  129.  
  130.     /**
  131.      * Scope for the background task, allowing for progress updates.
  132.      */
  133.     inner class BackgroundTaskScope {
  134.         /**
  135.          * Publishes progress updates to the main thread.
  136.          *
  137.          * @param progress The progress value to be published.
  138.          */
  139.         fun publishProgress(progress: Progress) {
  140.             this@AsyncTask.publishProgress(progress)
  141.         }
  142.     }
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement