how to prevent race conditions in my case - android

I am doing an android app and I have an UI to show some data received from the server. The data is saved in the db in a controller.
When the app is started, this is what it is doing:
the controller instance is initialized on the Ui thread, it is singleton. The initialization is lightweighted. The UI will call the controller method to get the data saved in memory and show it.
having a worker thread to execute some controller method to read the data from db and save it in the cache in memory and notify UI after get it.
whenever there is some new data, the server will send a push to the client where an intentservice is started and the controller talks to the server to get the data and update the cache and after it completes, it notifys UI.
So the question is the 2 and 3, since both are running in different threads, so in order to make sure the db must be read and save in cache first, I have a flag in 3) so that before writing the new data in the memory, I always check the flag first. It will work but since I can foresee there will be more operations on the cache probably cross different threads and I really don't want to add the flag checking in all such places, so do we have any pattern/way to make sure the 2) always happens first?
sorry that I didn't find any similar post on it. thanks.

ok do one thing when your statement 2 is complete the execution at the last line of code call a broadcast receiver and inside onRecieve() method which is inside the BroadCastReceiver execute the statement 3.

Related

Invoking Firebase listener to run

I'm trying to determine whether or not I download data in my android application. I can do this by making the method return true when it does download data, but the listener doesn't seem to be invoked until all other code is finished running (meaning it waits until a pause in your code). So I'm wondering if there is a way to sort of "forcibly" invoke these listeners? Perhaps by creating the listener in a different thread? Would this work or would it be a waste of time? I've already tried to sleep on the main thread for a few seconds, but that doesn't seem to do it either. If it wouldn't work, could you explain when exactly these listeners are invoked? Thanks in advance.
To add onto my question, I am NOT using the realtime database. I understand how realtime triggers work, but I am using the Firestore, so I am only getting data once, not getting realtime updates :)
As you have already noticed with the API calls that deal with reading and writing data are fully asynchronous. This means that the call always returns immediately, without blocking the code to wait for a result. The results come some time later, whenever they’re ready, since it may take some time for this. Depending on your connection speed and the state, it may take from a few hundred milliseconds to a few seconds before that data is available. So Firebase, already is using another thread (other than the main thread) to get the work done.
Calling a synchronous function on your app’s main thread could freeze the app indefinitely, which is a terrible UX. On Android, it could also soft-crash with an Application Not Responding (ANR) dialog.
Doug Stevenson, has explained in his post everything that you need to know about Fireabse asynchronous behaviour and what you need to do/avoid when dealing with Firebase.

Getting data from server regularly even when the app is closed

I want to get data from the server and store it in a cache regularly, even when the app is closed. I am not sure what is the correct way to do it. I have listed down the possible ways I can think of. Please let me know the correct or the best way to do it. Really appreciate any help.
Create an Activity and set a repeated alarm to call a service. The service should connect to the server and download the data in cache.
From a fragment, check the last time the cache was updated and then if the data is out-dated, connect to server in a background thread and update the cache.
You can Directly Use IntentService for Frequently Updating Data
IntentService is a subclass of android.app.Service class. A stated intent service allows to handle long running tasks without effecting the application UI thread. This is not bound to any activity so, it is not getting effected for any change in activity lifecycle. Once IntentService is started, it handles each Intent using a worker thread and stops itself when it runs out of work.
IntentService would be an best solution, If you have an work queue to process. For example, if your application using analytics you will likely to send event name and related parameter to your tracking server for each user generated event. Although each event means a tiny piece of data, creating networking request on each click will result an overhead to your application
For implementation : Updating Data from Server Using Intent Serive
Do take a look at Android Sync Adapter Framework.
https://developer.android.com/training/sync-adapters/index.html
Hope this helps.

Android AsyncTask get() form another AsyncTask()

Background
I have an AsyncTask (call it uploadHeader) that uploads some data to a server.
I have a second AsyncTask (uploadDetail) that uploads some related data, which requires the initial data to have been uploaded: the header upload returns an id issued by the server, which is used to update the local detail records, before they're uploaded.
If at the time uploadHeader was initially called there were connectivity issues, the header info won't have been uploaded.
So at the start of uploadDetail.doInBackground() I check the status of the local header record to see if it has already been successfully uploaded to the server, and if not, call an uploadHeader.get() to upload the header and wait to get the id back, before I upload the detail records.
Problem
It just seems to hang at the get() call. Debugging it, it seems to be creating a FutureTask and then looping somewhere inside that. It looks as if the second AsyncTask is being queued to run after the first one finishes, which it never does since it's waiting on the second.
I've read a number of other posts/articles on calling one AsyncTask from another, but they all seem to be focused on getting the two to run in parallel. I want this to block, until the other task finishes. It's also been mentioned that "execute(Params...) must be invoked on the UI thread.", none of the articles mention get(). Or is get() basically identical to execute() apart for waiting for the result?
As a workaround, I could put the http call to upload the header in a separate class and call that from both uploadHeader and uploadDetail, so uploadDetail wouldn't need to create an uploadHeader task.
I'd just like to understand why it's not working as it is.
get() will block your execution until the second AsyncTask returns a value, don't do this if your first AsyncTask is doing some work that repercutes on the user interface of even in the workflow you've designed.
I'd definitely use Handlers on both AsyncTasks to communicate between them, even another one for the UI if you need to. You may find a good example here. For reference, look here.

Android Querying Web Service in Real Time

I have written an application that queries a web service I wrote (which returns JSON data). My app currently processes the web service call using an AsyncTask and updates a TableLayout with the data it receives. I want my app to regularly (every second or so) call this web service and display the data in the DB, as it is continuously being updated. How can I go about doing this without having the UI thread block?
Currently the way things work is the user presses a "go" button, and the AsyncTask displays a "loading" dialog while the request processes. I would like for them to press the go button once and have the data refresh in the layout. I'm not sure what the best way to architect this is.
I wouldn't recommend that you create a new AsyncTask every second since this is going to result in a lot of object creation and corresponding memory collection.
What you can do instead is create an AsyncTask that after each request returns from the web service updates some internal data structures and then calls publishProgress(), waits the appropriate amount of time, then makes a new request to the web service. In onPublishProgress() the code should then get the new information from the request from whatever internal structures are being used (don't forget to use a lock here to synchronize access) and refresh the UI.
You'll also want the AsyncTask to have a method or variable that the Activity can call to tell it to break out of the loop.
You can use a Handler which can initiate a new AsyncTask request after every second.

Android simultaneous db operations -- "database is locked"

I'm writing an application with an "online mode", that is, data is downloaded, parsed and inserted into a SQLite database as needed. All this is performed by a service. The app consists of several activities that ask the service for a data update (different data depending on the activity).
When the user navigates through the activities (without waiting for the service to finish), it's very easy to get SQLiteExceptions (message: database is locked).
I thought about using synchronized blocks, but that would force the user to wait while loading a new activity (that needs database access to load) while the service finishes updating. So that seems a dead end.
Another option might be to stop the update when in the onStop method of each activity. Of course, the update will be interrupted, but that's not a big issue. Problem with this is that I'm not sure how to approach it.
My question is, how can/should I handle this?
If your activity is only going to read and not write to database like my case, this is what i did as a workaround:
create a service ( i.e DatabaseService 0 and use it as a central point to access database (i.e open a database connection) to ensure you only have one dbhelper at a time.
all activity and service which need to access database have to establish a connection to DatabaseService
ensure that only your DownloadService's thread is able to write to database and it should use transaction
after that, you can use getReadable database to read / use the connection to stop the download service , etc.
Just make sure that you only use 1 dbhelper.

Categories

Resources