I have a working service that allows users to send emails over Ethernet. This service is a part of a greater application that allows users to view the progression of those messages (both sending and receiving) as they are transmitted.
My service is responsible via callback interfaces for notifying when the queue of messages changes (a message is added or removed) as well as notifying when a message update occurs (the progress or status of a message has changed ex., 50% -> 75%, "receiving" -> "decoding"). When the queue is changed, this interface passes in a list of message now/still in the queue, roughly like so:
public void MessageQueueChanged(final MessageProps[] queueMsgs) {
if (queueMsgs.length != 0) {
for (MessageProps msg : queueMsgs) {
//Iterate through each message and
store it in a data structure//
}
}
}
And when the service reports a message update occurs, the data structure should likewise be updated:
public void MessageChanged(MessageProps msg) {
//if msg is in msg queue/data structure
//update in data structure
}
Each msg has a unique guid to identify it, and preferably the data structure that is used to store this message queue handles notifying the UI that it has changed so as to redraw. Once a message has left the queue, I don't need to care about it; I only want to "know" about it for the duration of time I should be displaying it, i.e. as it is being sent or received.
The heart of my question is: What options do I have for storing and displaying this kind of transient message progress? Messages may be updated multiple times very rapidly (the order of milliseconds) but a messages lifecycle is just how long it takes to transmit.
I originally tried using a simple ArrayList<> with a RecyclerView, with a seperate Hashmap that kept track of live message guids, but I kept running into some internal RecyclerView crashes, similar to this issue: RecyclerView: Inconsistency detected. Invalid item position
I was thinking of using a ContentProvider to store each message, since there is some other functionality that could utilize it cleanly, with a regular old ListView as my display. But this had me questioning how to keep track of which messages were 'live' - without that Hashmap of live guids, I'm not sure the most effective way to query the content provider for live messages. Keeping that hashmap around though seems wrong though. I also thought of maybe just deleting messages from the content provider once I was done with them, but was unsure if that was efficient or safe to do; either via dropping the whole table when it was safe to do so, or deleting by row.
Thanks for reading this far, and I hope what I'm asking is clear. I am happy to clarify or expand on anything; I didn't want to get overly specific so I hope I captured the heart of my problem.
In the end I settled on using a ContentProvider to store and update my message information as it came in; a SimpleCursorAdapter to handle the display and loading of the relevant messages; and an ArrayList of type String to track via guid the actively updating messages.
I found that that the SimpleCursorAdapter was sufficient for displaying this type of simple data yet was stable enough to handle the large number of redraws required.
I would be happy to expand upon my answer/share relevant code details should someone seek a similar solution.