I am working on a app that syncs data over the network, and inserts user data in a database. To avoid slowing down the UI thread, both database queries and network requests run in the background.
At the moment, both are implemented using AsyncTask, started with executeOnExecutor(AsyncTask.SERIAL_EXECUTOR). The problem is, if a network request is taking a long time, database writes will be delayed by that much. Is it possible to have multiple SERIAL_EXECUTORS (in this case, two)?
If not, would the basic implementation of SerialExecutor shown in Google's documentation be enough?
Related
I need share some data between Android devices live (at least every 5 seconds update). I first had in mind to create an async task in which the one device sends its own data to a server and gets the other data as response. I recently read about firebase or synchronized database so I was wondering which is the best way with keeping performance in mind.
I'm not asking for code but for ideas to improve my app. I also need to save the "old" data from each client for a history.
There is no need to use AsyncTask
For implementing Firebase operations. Firebase is already optimized. So you don't need to use a background thread for performing network-related operations using firebase.
firebase childevent listener frequently checks for database changes and you can show them on the UI screen, no async task needed.
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.
I've an android app where I'm retrieving data into a Fragment. And I believe that Firebase manages its asynchronous calls. But still I've doubt the if we need to write the Firebase code in the background thread or not?.
If we need to write it into the background thread then can you please tell which operations takes more time. eg:
mDatabase = FirebaseDatabase.getInstance().getReference().child("Blog");
I think that performing this on the main UI thread may become risk full because setting connection between database may sometime take large time.
The Firebase Database client performs all network and disk operations off the main thread.
The Firebase Database client invokes all callbacks to your code on the main thread.
So network and disk access for the database are no reason to spin up your own threads or use background tasks. But if you do disk, network I/O or CPU intensive operations in the callback, you might need to perform those off the main thread yourself.
If you're pulling down a large-ish collection of data from the database, and you want to convert that all into a JavaBean type collection, you may want to offload that onto another thread as the size of data its use of reflection may cause too much work for the main thread. The only way to know about this for sure is to benchmark it yourself. Generally speaking, you get 16ms to do things on the main thread before you start dropping from the optimal rendering speed of 60 frames per second.
I recently tweeted a diff on a project of mine where I refactored a pattern for sending database listener to an Executor for background processing. However, your app may not call for this kind of complexity. It was good for my app, however. https://twitter.com/CodingDoug/status/773277680867258368
Firebase runs all of its callbacks asynchronously as documented https://www.firebase.com/docs/android/guide/retrieving-data.html . This is done through a web socket layer.
If for example, you need to do a large amount of data processing on the result of the Firebase data update - you should probably spin up an AsyncTask to prevent the UI from blocking. This isn't any different from how you would normally approach data processing before being presented to the UI.
The Firebase documentation covers how data is handled and the reason why you do not need to execute any background reads. You should probably spend some time reading the documentation.
After doing some research it is still not clear to me how exactly Android downloads data from Firebase. Android has a lot of best practices for performance such as using an AsyncTask or Volley, but I need to understand how Firebase operates before I can make decisions about them.
To be more specific, does Firebase load data in a separate thread? When I am downloading profiles (a profile picture with some text) in a FirebaseRecyclerAdapter I would like to download the text for each profile first and the pictures in a separate thread. I know how to do this when downloading data from the internet normally but I do not know what Firebase already does.
Firebase uses a single separate thread for all its (network, disk, etc) operations. But your callbacks will always be invoked on the main thread, so that you can safely interact with the UI.
But if you perform any non-trivial operations in the callback, it is (as usual) your job to perform those operations off the main thread. So a AsyncTask or IntentService are still the proper approach there.
I am trying to understand the possible ways to work with SQLite when there can be multiple threads work on DB.
Based on various responses in stackoverflow and other sites, it appears that there will be locking issue when same sqlitehelper instance is used from multiple threads. In a typical java application, I would expect instance to mean single object of type sqlite helper to be used by different threads of application.In such cases, the locks ,I guess, are a matter of correctly using the synchronized blocks. [Correct me here as I am not comfortable with this way of looking at sqliethelper instance here]
My concern is with sharing same data base : when one instantiate sqlite helper in different threads [ie each thread has its own object instance] but working on same Database [this I guess is more inline with having same db instance].
In such cases I'm getting frequent database lock errors. This occurs even when the threads are working on different tables of database.
In my application database can be updated by user interaction through application or by getting data through server [periodic synchronization]. And some time when synchronization process and user activity overlaps, I get the lock issues. As this pattern of data processing seems to be common in application synchronizing with server, would like to know how do lock issue due the concurrency is to be handled.
I would like to understand this since if this is bound to happen always then probably need to make only one handler over database and implement queue over that to avoid lock. But that will mean the complete application needs to be aware that the database may not get updated immediately and they need to implement listener to know when the data is actually updated in database.
thanks
pradeep
As far as I know sqlite is intended for single process usage. No matter what you will always need to access the database from one thread at a time. You can do selects from multiple clients but can only write from one at a time. And other readers and writers will ahve to lock in the mean time.
As a side note - database access can hardly ever be considered instantaneous.