Created
February 10, 2023 14:17
-
-
Save GibsonRuitiari/589b3dbf75180c284160494e1223748c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.gibsoncodes.myapplication | |
import android.os.Handler | |
import android.os.Looper | |
import android.os.Message | |
import android.util.Log | |
import java.util.concurrent.CountDownLatch | |
/* | |
initialization of this dispatch queue must be done typically by a singleton class/obj. | |
for example | |
```object DispatchQueuePool{ | |
fun getDatabaseQueue() = DispatchQueue("DatabaseQueue") | |
fun getNetworkQueue() = DispatchQueue("NetworkQueue") | |
}``` | |
.. in your other class possibly do | |
DispatchQueuePool.getDatabaseQueue().postTask{..} | |
when the application is nearing onDestroy state remember to recycle the queue to remove the looper | |
associated with this thread | |
*/ | |
class DispatchQueue constructor(threadName:String, start:Boolean): Thread (){ | |
constructor(threadName: String):this(threadName,true) | |
private val dispatcherQueueTag ="DispatcherQueueTag" | |
init { | |
name = threadName | |
if (start){ | |
start() | |
Log.i(dispatcherQueueTag,"Starting dispatcher queue thread! Thread name is $threadName") | |
} | |
} | |
private val countdownLatch:CountDownLatch = CountDownLatch(1) | |
private var handler:Handler?=null | |
fun sendMessage(message: Message) = sendMessage(message,0) | |
fun sendMessage(message:Message, delay:Long){ | |
try { | |
countdownLatch.await() | |
if (delay <= 0) handler?.sendMessage(message) | |
else handler?.sendMessageDelayed(message,delay) | |
}catch (ex:Exception){ | |
// swallow the exception | |
Log.w(dispatcherQueueTag,"the following error occurred while sending message $ex") | |
} | |
} | |
fun handleMessage(message: Message){ | |
try { | |
countdownLatch.await() | |
handler?.handleMessage(message) | |
}catch (ex:Exception){ | |
Log.w(dispatcherQueueTag,"failed to handle message because of $ex") | |
} | |
} | |
fun cancelTask(runnable: Runnable){ | |
try { | |
countdownLatch.await() | |
handler?.removeCallbacks(runnable) | |
}catch (ex:Exception){ | |
Log.w(dispatcherQueueTag,"the following error occurred while cancelling the runnable $ex") | |
} | |
} | |
// cancel an array of tasks | |
fun cancelTasks(tasks:List<Runnable>){ | |
for (task in tasks){ | |
cancelTask(task) | |
} | |
} | |
// free up any tasks by removing them mostly paired up with cancelling tasks | |
fun cleanUpQueue(){ | |
try { | |
countdownLatch.await() | |
handler?.removeCallbacksAndMessages(null) | |
}catch(ex:Exception){ | |
Log.w(dispatcherQueueTag,"the following error occurred while recycling the queue $ex") | |
} | |
} | |
// use this when you are completely done with this queue | |
fun recycleQueue(){ | |
handler?.looper?.quitSafely() | |
} | |
// check if we can start posting tasks | |
fun isQueueReady():Boolean = countdownLatch.count == 0L | |
fun postTask(runnable: Runnable):Boolean = postTask(runnable,0) | |
// post a task to our handler | |
fun postTask(runnable: Runnable,delay: Long): Boolean { | |
if (handler==null) { | |
Log.w(dispatcherQueueTag,"A handler instance is not created!") | |
return false | |
} | |
try { | |
countdownLatch.await() | |
}catch (ex:Exception){ | |
Log.w(dispatcherQueueTag, "the following error occurred while posting a task $ex") | |
} | |
return if (delay <= 0) handler!!.post(runnable) else handler!!.postDelayed(runnable,delay) | |
} | |
override fun run() { | |
try { | |
Looper.prepare() | |
handler = Handler(Looper.myLooper()!!){ | |
handleMessage(it) | |
true | |
} | |
countdownLatch.countDown() | |
Looper.loop() | |
}catch (ex:Exception){ | |
Log.e(dispatcherQueueTag,"the following error occurred while running the thread $ex") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment