I am currently developing an android application using HTTP/REST requests to communicate with my backend. I am not using any particular library yet since until now the built-in HttpURLConnection works fine for me. However I would like to have some kind of fallback mechanism if my requests fail due connectivity issues. A similiar problem is also described in https://stackoverflow.com/questions/31786486/android-volley-internet-queue but has not been answered yet and other related posts rather focus on caching older responses to redirect requests to the cache when there is no connection is available.
Up to now I considered using Volley but as far as I understand it it only allows to retry a failed request until it finally connects. I think it would be a cleaner solution to cache the failed request and attempt to resend it after I registered a change in my connectivity state via a BroadcastReceiver. Is there an existing solution which does that for me or do I have to set up an internal database and manage the whole process myself ?
TL;DR
I want to store failed HTTP/REST requests on my android device when my device is offline and resend them when the device can establish a connection again. What am I looking for ?
I had the same situation with a reporting service. What I implemented was a Service that receives requests and queues them. In a separate thread (started when the service starts) it checks the queue and attempts to make the connection. If you use a BlockingQueue you have the 'signalling' between threads for free, so you don't need to idle-poll.
You can use set up a receiver for WifiManager.WIFI_STATE_CHANGED_ACTION and/or ConnectivityManager.CONNECTIVITY_ACTION events, so that you start the service or wake up the thread and attempt to re-send when the connection is up again.
I suggest a Service so you can detach all this from the code in your Activities and have some facilities for starting and stopping it. I personally used an IntentService because that allows me to serialize the requests through Intents, and let the OS handle the Intent management sending for me. You might implement it differently, even without a Service, just with a Singleton object.
If you also need storing them when your app is not running, I would use a SQLite Database.
As #Sebastian wrote you can write queue handler yourself, or perhaps check if existing implementations, like android-priority-jobqueue is not going to be useful for you.
Related
I have constructed a background service in which, every particular interval, a request to the server is made which - in successful cases - a JSON response is parsed.
I am using Retrofit API to handle this situation, but I have come to a point where I wonder if this is the most efficient solution.
Should I use sockets or some other kind of API? Is this memory efficient?
Yes, Socket is the best way for continues connection or network calling, And also faster calling if you are using socket,
Also throw socket you can make like live connection, But for continues connection in background you need to create service and manage properly.
Push mechanism is the most efficient way than Polling(network request to server in intervals), provided the server supports push mechanism.
You can refer this for GCM.
https://developers.google.com/cloud-messaging/gcm
But in case if polling is the only way, you case use any of these
Service
Handler
AlarmManager
https://developer.android.com/training/scheduling/alarms.html
https://developer.android.com/training/best-background.html
I am relatively new to developing Android apps. I have an android app that downloads several resources from the internet and keeps on generating these requests. I want to create a queue of such download requests when there is no internet connectivity and get them started as and when the connection is restored. In this case, the connectivity may be in either form both Mobile data as well as over Wifi
There are several parts to this: first, detecting whether you're online now, if you're not online detecting when you'll come online, and having the actual queue.
The queue itself can use a SQLite database. You just need to store enough information to reconstruct what the request should be when you resume.
You can see the documentation on monitoring the connection state here.
Basically, if you're targeting API less than 24, you register a broadcast receiver to receive the CONNECTIVITY_ACTIVITY broadcast. (Otherwise, you can "listen" for CONNECTIVITY_CHANGE). Your logic once you figure out what request you want to queue will probably be something like the following:
Push request onto the queue
Check to see if you have connectivity
If so: start processing the queue.
Otherwise: wait for a broadcast receiver to notify you that you have connectivity again and start your service that does the processing.
Sorry to be a little vague (I'm not sitting in front of an IDE right now) but hopefully that outline'll be at least semi-useful.
There's a number of popular "job queue" libraries that allow you to specify dependency on network being available (along with various retry policies). For example:
https://github.com/yigit/android-priority-jobqueue
https://github.com/evernote/android-job
Create a local database which should have HTTP request details, time stamp and its status. Whenever your application initiate HTTP request store it in database with HTTP request details and time stamp of its initiation and its status to non completed.
When your HTTP request is complete change its status to complete so when your Http request generates some kind of exception or error you don't have to do anything.
Now your application should have a connectivity broadcast listener so when your application connects with internet read your database and initiate your HTTP requests.
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.
My app has a UI and a connection is made to a bluetooth device which is periodically sending barcode scan data to my app. I then want to cache this data in a sqlite db and have another process push this data up to a web server.
I have managed to get the UI and bluetooth scan process separated by using an Intent Service for the scanner component... The thread in the intent service connects to the bluetooth device and loops endlessly pulling in new scan data as it comes... communicating with the UI via broadcast messages as it needs to.
So now I need to handle storing the data in a sqlite db and pushing it up to the Internet.
I'm thinking I can insert a db row directly in the intent service loop I already have working for the bluetooth data... would I do that by firing of an async task or something like that?
Then, would I have a completely different intent service running and looping endlessly checking for new records to be processed and pushed up to my web server via an http post?
I guess the main reason I'm thinking of using intent services is that they seem to keep running even if I lock my phone and put it in my pocket... has worked so far for the bluetooth barcode scanner... can scan away happily with my phone locked and in my pocket.
I also need to handle the reality that internet won't always be available... hence the sqlite db... kind of like a safe buffer to store data until it can eventually be pushed up to the Web server.
Am I going down the right path? I'm really new to Android development and even after much research I'm still unsure about my approach.
You can store data or communicate from IntentService onHandleIntent() directly. You don't need to run it in separate thread, unless you want reading bluetooth to continue ASAP.
Handling everything in an infinite loop smells. Also keeping service alive depends on few factors. If IntentService dies, it won't be restored because by default IntentService.onStartCommand implicitly returns START_NOT_STICKY, or START_REDELIVER_INTENT if you call setIntentRedelivery(true) on this service. Check Service javadoc for more info.
If you can scan bluetooth periodically then I would consider kind of scheduler. For that you would probably need to implement Service, not IntentService and handle background thread yourself. Alternatively, you could use a Timer. These are more hints, not ready solution. Since you asked about direction, I assume you will investigate solutions yourself.
Depending on handled data you could separate DB operations and network to separate services. Think about them as modules which are decoupled. You will benefit maintaing this code in the future and in case one service goes down due to any reason, the rest will keep working. It depends on data size because it's not a good practise to push heavy data between service/activities(data is serialised and deserialised every time it is sent).
If DB is just a buffer/queue then maybe use it directly after reading bluetooth data. In other words queue data for sending. Create second service for HTTP communications. Don't push entire data to second service, just inform it about(knock the door :)) and let HTTP service access DB by itself. I would wrap DB in ContentProvider and access it from services.
There are probably different techniques out there too, but that's what I thought about it in the first place.
My architecture will use ActiveMQ on the server and have Android clients send and receive messages.The network situation will be very unreliable; possibly hours of missing connection. Is there a framework that will allow me to queue up the messages on the android client and deliver them reliably once the connection is back?
You can efficiently implement one yourself, I don't think anyone will provide you this service, and if they do they will certainly charge, Here is what I can suggest for an optimal solution.
Design a db using SQLITE to hold you message, once a message is ready for deliver from android client, you can perform the following
a. If network is avaibale, then you can directly deliver message to your web clinet
b. If network in not present, then cache it directly to you local android db
Design a Sync logic, you can achieve it by network listener, so when user device comes back into network,
you can write a logic to query from databse and posting to your webclient, deleting local data subsequently
upon successful posting into server
You can strengthen you logic, by caching message everytime into local db first, then a Sync logic which will commit your local changes to web server in bulk, thus improving upon processing time.
Hope this answer your problem.