Skip to content

Instantly share code, notes, and snippets.

@GibsonRuitiari
Created February 10, 2023 14:17
Show Gist options
  • Save GibsonRuitiari/589b3dbf75180c284160494e1223748c to your computer and use it in GitHub Desktop.
Save GibsonRuitiari/589b3dbf75180c284160494e1223748c to your computer and use it in GitHub Desktop.
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