I wrote an application with behavior like this: "Android client will run a service to send a request HTTP POST to server, server will return data in JSON and delete it from Database".
Problem I got here is: When i start LoadDataActivity (this activity will start service "GetMessage" to receive data froLm server). If i start LoadDataActivity and finish this activity immediately (Service GetMessage will stop too) , that's mean I sent the HTTP POST to server but I have not receive the JSON result yet, while server deleted it in db, so i lost this data.
Is there anyway to help me fix it, but dont have to keep service still running when finish activity?
What you're doing is a bad idea and you need to change some architecture here.
Just because you sent an HTTP request to a server does not mean that the client will get the response. YOu could lose internet connection. A router can break. Someone can trip over a wire and pull it out. The server could crash after deleting the data but before sending it. It's a bad idea.
If you want to do this, you ought to do 1 of 2 things:
1)Have the client send a 2nd request to the server telling it its ok to delete the data now. Do not do it in one request.
2)Use Lazy Deletion. Rather than actually delete the data, add a column "IsDeleted" to the db. Its default should be 0. After sending the data, set it to 1 rather than deleting it. Then change all queries to the table to only return rows where IsDeleted is 0.
Or 3) 1 and 2 combined. This is the best answer.
As for your direct question- no, there's no way to force the HTTP result to come before an activity is finished. So this needs to be done in a service that is started, not bound. An IntentService would work well, so you could have it automatically terminate itself when the request is done, and it would just start a new instance if another request is pending.
Related
I've been reading that we dont need to use AsyncTask when working with volley. I had a question though, one of the button click in my activity triggers a HTTP request. Now in case my app is closed, will volley still be able to process that request.
When I launch my app again, is it possible to figure if my previous HTTP request was sent or not.
What would happen to the response? Will I be able to catch the response and maybe make some db updates (local to app)?
What is the right design to do these kind of http requests?
Also, in case I want to make some HTTP requests while the app is not launched, can I not use a background task to do all this with volley?
You don't need to use an AsyncTask or Thread for Volley because Volley does that for you. So that's correct.
When you say your app is closed- do you mean the app is in the background, or the app is terminated? In the first case, the request will continue. In the second, it will not, and any response coming in would be ignored at the OS layer because there's no listening app on the socket. Also remember that apps not in the foreground can be killed by the OS at any time.
You can't send an HTTP request when your app isn't launched. You can do so in a JobScheduler or WorkManager item, but then your app is launched, you just aren't showing a UI.
I am currently storing my transactions in SqLite DB if there is no internet connection at the moment and when there is internet available i send the pending transactions with the new one made so making it quite a lot of data and a lot of API hits which chokes the device and it becomes unresponsive. So need help with a proper way to sync these transactions to the server. Also these are being sended to a Socket as well as a Server.
I tried using AsyncTask for it but it also causes problems if transactions are above 200. Tried Retrofit for it and to some extent the count exceeded from 200 to almost 350 but the issue and unresponsivness remains.
You should give a try to PriorityJobScheduler lib or WorkManager from JetPack.
When there is no network connection you can queue those request and those request will be send ones network connection is available. (So you dont need to wait until someone made new transaction to send old queued data too)
Also, in your current scenario, rather than sending single request for each transaction, ask your API Guy to accept request in List of object format. So you just need to create list of request body object and send to server
I've been wondering if there is any way with Volley to queue and then execute a request until the mobile data connection is available.
I have to create an Android app that have to work in areas with no mobile service, so I have to queue and postpone any POST request that my app perform using Volley, until the internet mobile service is available.
The app have a registration form that have to be filled, and when I press send, if there is mobile service the form is sent, but if not, the form information have to be store and the POST request have to be queue in order to be performed later when the phone count with service connection.
Is there any way to do this with Volley? Or with any other Android HTTP Connection library.
Thanks
I saved my information to a database on the device with a "transmitted" flag. This way, even if the user completely closes the app, the information is always saved.
I then created a service (https://developer.android.com/training/run-background-service/create-service.html) that checks every 15 minutes for records that have not been transmitted. If they are found, it tries to transmit again.
The transmit is also executed as soon as a user enters and saves the information. Successful transmissions update the "transmitted" flag on the record.
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.
I have faced a very weird problem by using Soap object in android. I am running a background thread which will take care of sending data to server periodically. Here i am using Soap web service for sending data. While sending a data to server,Sometime duplicate request(double time sending same data) occurs in server.
How to overcome this issue? Please help me...
Thanks in advance...
Firstly check if there's any loop/condition which is causing the error.
Secondly always within a thread whenever HTTP requests are involved make them synchronized and set a boolean whenever request is fired. Reset the boolean ones the response is received successfully and then fire the next request.
These requests for synchronization can be queued in a list and ones a successful response is received remove the request from list else pop the request out and place according to your need (logically back at the end - so that other requests also get a chance if one is failing repetedly).