I'm about to write an application that sends data to a server with a post request. These requests can fail and if they do I want them to be sent when the connection is back online.
What is the best way to implement this behavior?
EDIT
I've read some articles and come up with the following idea. I register a BroadcastReceiver in the manifest and tell it to listen for android.net.conn.CONNECTIVITY_CHANGE and android.net.wifi.WIFI_STATE_CHANGED. When the request can't be send I store the request. If the connection becomes alive then I will send the cached requests.
What is the best way to implement this behavior?
Make Volley requests from a bound Service, and send the result back to the Activity if it is still in the foreground.
EDIT:
won't this be a problem if the user decides to close the application?
That's exactly why you need to use a Service. If you do it from an Activity, the request continues even when the Activity is dismissed. If your Volley request is expressed as an anonymous class instance, it continues to hold an implicit reference to the outer Activity class, which leads to a memory leak / exception.
Check your Internet Connection continuously by using Handler or service ,if it is sends the data to the server otherwise dont send it.
Related
I hope I can explain this well ...
I am trying to understand better how to handle HTTP callbacks in Android, so I have created a simple app that uses Volley for HTTP requests. It only has a button that triggers an HTTP request to a service that, basically, just updates a number in a database and sends it in the JSON response after 5 seconds. The Activity gets the response and displays the response in a TextView. I am testing it in a real device that has enabled the "Don't keep activities" option in Settings - Developer Options.
This is the scenario I am testing:
Start App.
Tap the button that triggers the HTTP request.
Inmediately after tapping the button, tap the device's home button to send the app to background. onDestroy method is called because of the "Don't keep activities" option.
Wait a few seconds for the HTTP response. I can see the device gets it because it is printed in the logcat monitor and the database is updated.
Before running the callback, I check that the activity is still alive. Since the activity has been destroyed, the callback is ignored. If the app is restored from background, there is no crash but the Network Response is missed. Also, if I tap the button again, it sends a new HTTP request and increases the number again ...
So, the questions are:
Which are the best practices to deliver network responses to the UI? I mean, if instead of a simple operation let's say it was a register form and I get a phone call or something that forces me to send the app to background, where anything can happens, how can I make sure to not miss the network callback? Is there something that could delay the callback execution until the app is again in foreground?
Is there a way to save a Bundle like the one in onSaveInstanceState after onDestroy has been called and restore it when app is again in foreground?
Let's say the information that the HTTP response contains is sensitive. Is there a recommended way to handle this case? I was thinking to save the response in the internal storage and check for it when the app is again in foreground, but I don't know if it is possible to do that after onDestroy has been called, or if it not a good idea with sensitive data.
Thanks in advance!
1)YOu can never miss the network callback. You'll be called even if you're in the background, unless your entire app (not just the activity is killed). You'll just get the callback while backgrounded.
2)No. If you need the result of a network call the next time the activity starts like that, I suggest you use a Loader to load the data. That way you can query for the Loader results next time, and start the request only if needed.
3)Do what I suggested in 2 and there's no need for this question, its all in app memory.
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'm making a login post request from android phone.
Returned result will be 'success' or 'fail'.
I can make this post request using either a IntentService or an Activity, both will work fine.
Case I'm concerned about:
Phone rings (activity paused/destroyed) before receiving the result from the web service.
Will I miss the result in this case?
I want the result of web service to be saved even if the activity stops before accepting the result.
Is there anyway it'll work using Activity or do I need to receive the result using an IntentService ?
It should be on the service, the best way of finding bad behavior like this is to enable strict mode on your application.
If you put it on the activity it will block the activity.
Any request sent from the Activity results in NetworkOnMainThreadException being raised - you must not call any http request from UI thread (How to fix android.os.NetworkOnMainThreadException?)
Delegating the request to IntentService and notifying Activity via Broadcast (opitionally prioritized Broadcast to handle cases when your Activity is in background while the Broadcast is delivered to the receiver) is the easiest approach I think.
Alternatively, you can use AsyncTask but you must handle screen rotation and remember about task cancellation.
You can extend AsyncTaskLoader and provide your custom loader but you still must remember about request cancellation (http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html).
An third-party open source, maybe? OkHttp allows you to execute asynchronous Http requests. In addition there is a cancel() method on a Call object which executes the request. Thus, you can easily use it in the activity
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/com/squareup/okhttp/recipes/AsynchronousGet.java
Indeed, the StrictMode is a good tool that validates errors during development.
I am trying to do the following and am looking into other people's experiences:
I want to have an HTTP server running on Android that receives GET requests from a client. From there, the server must deliver the query parameters to a Service that will do some processing (sometimes quite heavy). When the service is done, it sends back the data to the server that will then return the response.
Of course, the startService(intent) call is asynchronous so I'm wondering how to tell the server to wait for the processing to be done before sending back the response. At the moment, the inter process messaging is done with the Messenger and Message classes.
What sort of design would be able to achieve that?
Use a bound service (one that implements onBind()) and a transact call on the returned IBinder object. Or write your own AIDL to describe the service's synchronous interface.
You want to bind to your service on app startup, before the HTTP requests start coming, since the bind operation itself is async.
By the way, why does the functionality have to be in the service? If the service is in the same app, can you move it directly to the HTTP server class?
I am new to Android development and am not sure of the best way to go about handling the following problem.
Background:
I have a TCP client running on android talking to a server. this is up and running just fine however when moving to the next step i am unsure of what to do.
Problem:
I have a UI that draws based on a users touch. I need for the tcp client running on the phone to send the coordinates and some other data to the server. Also there are multiple activities in this process that would be sending data.
What would be the best way to handle this?
Here are some of my thoughts.
1) A class that would have a Runnable client that works on another thread (I think its is an invalid solution because it would not be easy to use the same connection on multiple activities)
2) A local service that can the main activity can start and the rest of the activities can bind to it and send data to it.
If the correct answer is number 2 I am a little confused on how a service like that would work. What I am thinking is that in the OnCreate() method of the service it will launch a tcp connection with the server. Once the socket connection is established I am a bit unsure of how to actually keep in communication with the service and give it the data it needs to send over the client.
You would start the service with startService(). Include in the Intent extras that contain your data to send to the server. The service would retrieve these extras in onStartCommand() and would have a background thread actually send the data.
Be sure to stop the service when you are done with it.