What is the best way to make a deferred simple okhttp3 web request like:
Request request = Request.Builder().url(url).post(body).build();
Response response = client.newCall(request).execute();
that gets executed as soon as a client goes online and only then to handle result?
For example, client makes change to the data locally and this change should be posted on server. But there are cases when user does it offline, but we still have to handle it.
You can use a broadcast receiver which listen for internet connectivity changes, and Deferred library for deferring the request Jdeferred.
If use of deferred is too much work and overkill, You can use a conutdownlatch and
wait on separate thread until, the connectivity change, but the wait time can be huge, so chose wisely.
You can also consider CompletableFuture. But this is available from api 24 only
Let me know if you need more clarification.
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.
My intention is to stop receiving data from the server after the user has moved away from the activity which has made the service request. The motivation is to reduce the unnecessary bandwidth consumption as the user has navigated away from the activity and hence, the data is no longer required.
As far as I know, in Volley, it is only possible to cancel a request if it's in the request queue and not if it has already been sent.
So, is there any way to refuse the data being sent to the phone from the server or else, change the priority of the data acceptance to a lower level?
You can cancel the Volley Request which means you will not receive the response. When you are initiating Volley Request the request tag and cancel it via tag.
Hope this helps.
I have read somewhere that it is better to check internet connectivity before making http requests to avoid http exceptions.
Why don't we rely on http exceptions ? We can put it in try catch block and handle it.
I would say that if there's no internet connection, it doesn't execute at al. If you're using a try catch, it executes everything untill it doesn't work anymore, which is simply a waste of processing code.
This is opinion based as it is related to developers choice whether to check internet connectivity or rely on try-catch block. If you have further processes dependent on the response then you have to handle it everywhere. Instead you can check internet connectivity prior to making any http request. I personally in all my apps use broadcast receiver for connectivity change whose responses are handled in all screens by passing the local instance of interface in connectivity check task run on connectivity change broadcast. So i get results in all the screens (fragments) visible to user and i alert user likewise or handle processes likewise depending on apps requirement.
Im currently using GAE from Android. I have a search operation which performs what might be a long running query on the datastore (called from AsyncTask). The user has an option to logout from the app while this process is still running. Without an option to cancel this request the actual logout has to wait until the process finishes and the control is back to the client (which, as i said, can take a few seconds).
Is there a way to cancel a call to a GAE endpoint while the server is running and return the control to the client ? Thanks.
p.s.
Obviously, cancelling the AsyncTask only is not enough.
Personally, I put the server comm in a service so that requests can (usually) finish regardless of what the user does. In your case, could you let the user log out, but also let the request complete?
Otherwise, I don't know how to cleanly interrupt an endpoint request. Unfortunately, the actual blocking operation is buried in the endpoints (Google API Client library) code and no cancel operation is exposed that I'm aware of.
When you write that cancelling the task - AsyncTask.cancel(boolean mayInterruptIfRunning) - is not enough, is that because you've tried it and it doesn't interrupt a blocked operation.
No, Google Endpoints use servlets and servlets have no (standard) way of telling a running request to cancel it's work. You will need to build something proprietary.
For example: in your long-running process on server you in it's main loop check if user is still logged in (via a flag in the datastore or memcache). If this flag tells you that user is logged out, then you cancel the processing and return. Also a login/logout procedure must appropriately set this flag.