In my application I have a socket UDP server which listens to broadcast messages and notifies the UI about the message with an interface to update the recyclerview to add the message.
I used to use a thread to listen to the port, but I'm trying to change the project to use Robert Martin's Clean Architecture, so I changed the thread to workermanager worker.
However, now I need a way to notify the viewmodel about a broadcast message received. How can I listen to the socket in worker and notify the viewmodel in a Clean Architecture-compatible way?
This is what I had previously:
Notifier interface:
interface PartyDiscovery {
fun onPartyDiscovered(party: Party)
fun onPartyEnded(party: Party)
}
This is the thread:
class PartyDiscoveryThread(val discovery: PartyDiscovery) : Thread("PartyDiscovery") {
private val TAG = "PartyDiscovery"
override fun run() {
super.run()
val buffer = ByteArray(2048)
var socket: DatagramSocket? = null
try {
Log.e(TAG, "run: Just Started")
socket = DatagramSocket(Party.defaultPort)
socket.broadcast = true
val packet = DatagramPacket(buffer, buffer.size)
socket.soTimeout = 100
while (!interrupted()) {
try {
socket.receive(packet)
val jsonData =
JsonParser.parseString(buffer.decodeToString(0, packet.length)).asJsonObject
val party = Party(
jsonData["partyId"].asLong,
jsonData["partyRoom"].asInt,
jsonData["owner"].asString
)
if (jsonData["action"].asString == "started")
discovery.onPartyDiscovered(party)
else if(jsonData["action"].asString=="ended")
discovery.onPartyEnded(party)
} catch (e: SocketTimeoutException) {
continue
}
}
} catch (e: java.lang.Exception) {
Log.e(TAG, "run: Party Discovery Crashed", e.cause)
}
socket!!.close()
Log.e(TAG, "run: Dying")
}
}
This is the activity:
class MainActivity : ComponentActivity(), PartyDiscovery {
lateinit var discovery: PartyDiscoveryThread
var isDiscovering = false
private val TAG = "MainActivity"
override fun onResume() {
super.onResume()
startDiscovery()
}
fun startDiscovery() {
if (!isDiscovering) {
discovery = PartyDiscoveryThread(this)
discovery!!.start()
isDiscovering = true
}
}
fun stopDiscovering() {
if (isDiscovering) {
discovery!!.interrupt()
isDiscovering = false
}
}
override fun onPause() {
stopDiscovering()
super.onPause()
}
override fun onPartyDiscovered(party: Party) {
// Add to recyclerview
}
override fun onPartyEnded(party: Party) {
// Remove from recyclerview
}
}