Introduction
Whereas simple apps without thread operations can be developed easily for iOS/Android systems (or desktops), things can get murky when threads get involved. So how do we deal with it?
Background
Most of the apps that I need to work on has to deal with multiple threads and over the years I have learnt some simple techniques (simple when you have learnt through your mistakes) and would like to share some of these for App development.
Say I am receiving some instant notification messages from server through sockets and I need to show these in a UI Page.
Since the notifications are coming through sockets, it most likely would happen in background threads. Very often more than one thread would be created while we receive data through sockets.
Most beginners run into the problem of updating the GUI and saving the data in the notifications that they receive which takes the app to a very unstable state.
So here are three key things to keep in mind while having a go at the problem:
-
Read/Fetch/Receive data in background to ensure the app doesn't hang/wait/freeze for incoming data. Socket notifications usually come through background threads anyway.
-
Write/Store data in foreground thread in short bursts. Usually posting a request to the UI/Main thread of apps to run storing operations automatically takes care of thread synchronization. Incase of expensive operations use a Queuing service.
-
Reflect changes in gui in main/ui thread.
Usually if we don't have to store too much info or update too many models we can simply post a request to the system to run the next set of operations in the main/UI thread once we receive data in background thread.
In our case if we receive server notification messages in onMessage event, inside the event handler we can use codes such as (depending on android/ios):
runOnUIThread/dispatch_get_main()
to update Model/DB as well as the UI
example pseudo code:
void onNewMessage(message){ runOnUIThread->{ // this usually takes care of the thread syncronization db.insertNewMessage(message); updateAllViews(); } }
Now if you feel the db/model operations can get expensive, you can implement a Queue service in background inorder to insert/update frequently incoming messages in DB/models. A message fetching service from the Queue needs to be implemented in the foreground to update the GUI accordingly . To keep things simple you can use event notifications (along with relevant info) from the Queuing service requesting the Main Thread to update the GUI.
The pseudo code example will look like the following in that case :
void onNewMessage(message){ QService.insert(message); } QService.onFinishProcessingMessage(message){ // the UI page/element might register as an observer into the event service EventService.notifyObservers("event_message_processed", message); } uiPage.on("event_message_processed", function(message){ // most likely the event notification would come in a background thread, // so invoke running in main thread for GUI operations/update runOnUIThread->{ updateUI(); } });
Happy Coding!
History
Article uploaded : 15th Nov, 2018