Created
June 23, 2024 07:58
-
-
Save Sal7one/f23e21ead9e0ad9b59cc2ddf45e15a48 to your computer and use it in GitHub Desktop.
It's the weekend and I miss handlers :]
This file contains 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 com.sal7one.handler | |
import android.os.Bundle | |
import android.os.Handler | |
import android.os.Looper | |
import android.os.Message | |
import android.util.Log | |
import androidx.activity.ComponentActivity | |
import androidx.activity.compose.setContent | |
import androidx.activity.enableEdgeToEdge | |
import androidx.activity.viewModels | |
import androidx.compose.foundation.layout.Arrangement | |
import androidx.compose.foundation.layout.Column | |
import androidx.compose.foundation.layout.fillMaxSize | |
import androidx.compose.foundation.layout.padding | |
import androidx.compose.foundation.layout.safeDrawingPadding | |
import androidx.compose.material3.Button | |
import androidx.compose.material3.Scaffold | |
import androidx.compose.material3.Text | |
import androidx.compose.runtime.getValue | |
import androidx.compose.runtime.mutableStateOf | |
import androidx.compose.runtime.setValue | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.lifecycle.ViewModel | |
import com.sal7one.handler.ui.theme.HandlerTheme | |
class MainActivity : ComponentActivity() { | |
private val viewModel: MainViewModel by viewModels() | |
private var mMainThreadHandler: Handler? = null | |
private var myCustomThread1: MyCustomThread? = null | |
private var myCustomThread2: MyCustomThread? = null | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
mMainThreadHandler = object : Handler(Looper.getMainLooper()) { | |
override fun handleMessage(msg: Message) { | |
super.handleMessage(msg) | |
handleHandlerMessssage(msg) | |
} | |
} | |
myCustomThread1 = MyCustomThread(mMainThreadHandler, 1, 50, 15000) | |
myCustomThread2 = MyCustomThread(mMainThreadHandler, 2, 10, 100) | |
myCustomThread1?.start() | |
myCustomThread2?.start() | |
enableEdgeToEdge() | |
setContent { | |
HandlerTheme { | |
Scaffold( | |
modifier = Modifier | |
.fillMaxSize() | |
.safeDrawingPadding() | |
) { padding -> | |
Column( | |
modifier = Modifier | |
.padding(padding) | |
.fillMaxSize(), | |
horizontalAlignment = Alignment.CenterHorizontally, | |
verticalArrangement = Arrangement.Center | |
) { | |
Text(text = "Task 1: " + viewModel.message1) | |
Text(text = "Task 2: " + viewModel.message2) | |
Button(onClick = { sendMessageToBackgroundThread(1, "Start Task 1") }) { | |
Text("Start Task 1") | |
} | |
Button(onClick = { sendMessageToBackgroundThread(2, "Start Task 2") }) { | |
Text("Start Task 2") | |
} | |
} | |
} | |
} | |
} | |
} | |
fun handleHandlerMessssage(msg: Message): Boolean { | |
val taskId = msg.arg1 | |
val progress = msg.arg2 | |
val message = msg.obj as String | |
when (taskId) { | |
1 -> viewModel.updateMessage1(message) | |
2 -> viewModel.updateMessage2(message) | |
} | |
return true | |
} | |
private fun sendMessageToBackgroundThread(taskId: Int, message: String) { | |
val msg = Message.obtain().apply { | |
arg1 = taskId | |
obj = message | |
} | |
when (taskId) { | |
1 -> myCustomThread1?.sendMessageToBackgroundThread(msg) | |
2 -> myCustomThread2?.sendMessageToBackgroundThread(msg) | |
} | |
} | |
} | |
class MyCustomThread( | |
private val mainHandler: Handler?, | |
private val taskId: Int, | |
private val iterations: Int, | |
private val sleepDuration: Long | |
) : Thread() { | |
private var mHandler: MyThreadHandler? = null | |
override fun run() { | |
Looper.prepare() | |
mHandler = MyThreadHandler(Looper.myLooper()!!) | |
Looper.loop() | |
} | |
inner class MyThreadHandler(looper: Looper) : Handler(looper) { | |
override fun handleMessage(msg: Message) { | |
val taskMessage = msg.obj as String | |
for (i in 0 until iterations) { | |
sleep(sleepDuration) | |
val progressMessage = Message.obtain() | |
progressMessage.arg1 = taskId | |
progressMessage.arg2 = i | |
progressMessage.obj = "$taskMessage: Progress $i" | |
mainHandler?.sendMessage(progressMessage) | |
} | |
} | |
} | |
fun sendMessageToBackgroundThread(message: Message) { | |
mHandler?.sendMessage(message) | |
} | |
} | |
class MainViewModel : ViewModel() { | |
var message1 by mutableStateOf("") | |
var message2 by mutableStateOf("") | |
fun updateMessage1(newMessage: String) { | |
message1 = newMessage | |
} | |
fun updateMessage2(newMessage: String) { | |
message2 = newMessage | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the ability to kill it also