In my phone when minimize aplicatoin then the Android destroy activity.
In Developer options I turn "Don't keep activities".
I try to implement MVP.
I have a activity with button.
Steps:
User click button
As result activity call method from Presenter: presenter.dowanloadFile(). This is a async http request. The size of file is about 10 MB.
Show progress
After 10 seconds user get success http response
Presenter call method from view: view.hideProgress
OK. This case work fine. Nice.
But suppose the next case:
User click button
As result activity call method from Presenter: presenter.dowanloadFile(). This is a async http request.
Show progress
After 2 seconds user minimize application
As result activity is destroy (because turn Don't keep activities)
After 3 second user return to application
As result create new activity
After 5 seconds user get success http response
Presenter call method from view: view.hideProgress
The question is:
Is I need to continue http request when user minimize application (item 4). Or I must cancel current http request. And when user again return to application I must again start new async http request?
I want the next: When user return to application and if http request success finish then to show result. If the request is not finish then continue to wait http response.
It depends on what you want to happen? It seems like it's wasteful to cancel a request that is expensive (10 seconds is a lot), however you also need to consider what "cancel" mean in the context of an HTTP request.
For example, if cancelling a request, only prevents results from being delivered. Than means that your file was actually uploaded but you don't get callbacks anymore for that request result. Also be careful if your upload thread has a reference to your view, it will be leaked till the upload is done.
If you don't really care about the request, you can just cancel it. Assuming your server is smart enough to identify another request for the same file, so you don't duplicate it if your activity was re-created.
Another option would be not cancelling the request. Then you would need some mechanism of having your "presenter" survive the Activity re-creation.
There are numerous ways of doing that:
Having a cache for your presenters and not re-creating it if it exists in the cache.
Using headless fragments, which are basically are fragments with setRetainInstance(true) to survive an activity re-creation.
Moving your upload logic to a background Service or JobScheduler, and having your presenter/view only subscribe to the state of the upload process, but not actually own it.
You can investigate each option individually when you decide what is the most convenient for your application.
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.
I have a requirement in my Android app, that makes an HTTP request to the server to perform a long running task. The architecture on the server is that; the HTTP request returns immediately with a transaction ID. What I need next is to poll the server to check whether the job has completed and once completed show the result to the user.
When the first HTTP task completes I show a UI Fragment which has a progress bar asking the user to wait while the task completes. Ideally, I would like to show the result to the user on the same Fragment once the task has been done. But I would also need to consider situations where the user might press the Home button or move out of the app/screen in some way.
My current solution is:
Poll every 10-15s with some sort of exponential backoff, as long as
the activity is still attached.
The server sends a push notification regarding task completion - but
I'm worried about reliability of this.
Is there a better way to achieve this? If so, what would be a good design pattern for this? Are there any libraries available that handles this scenario?
I need to make a http request in my main activity and if the request completes while the user is reading the basic info in this activity, I must store the returned info in a variable. However, if the user clicks in a button in this activity, another activity will be opened. This new activity will continue waiting the same request started from main activity, and display the data when it finishes.
I've read about IntentService, however it can't be aborted (am I right?) and the user can ask for new data before the request is completed.
What alternatives do I have?
PS: The request will only work while the app is running.
PS2: I'm using Volley for http requests.
Sounds like you might want to use a Service instead of an IntnetService, since volley will kick off on a separate thread. You can then handle the management of the volley task in that service.
There are a few Fragments in my main activity. Different adapters are used in different fragments. Those adapters are used to make http requests to my web services.The requests work well except that it requests too frequently sometimes, for example when the device rotates. Actually I don't want to request if the last request is not long enough, for example, no more than 30s. But the problem is the Fragments will be recreated when the device rotates. So that the adapter will also be recreated and then the http request will be made.
Of course I can create a global queue for the request so that I can ignore the request when last the request is no more than 30s. But the fragment will be empty if I don't request because it's a brand new fragment.
Can anybody advise what the best practice for a proper http request in Android? Thanks
How about using an IntentService or ContentProvider to manage the requests i.e maintain a timestamp of the last request and only process the web service request if the last request was made X seconds ago.
While the fragment is waiting for content, show a ProgressBar (indeterminate = true)
I'm using Robospice. I want to write some reusable code to stop ProgressBars and ProgressDialogs as soon as pending network requests have cleared for the current activity. However, I'm running into a couple of problems.
I'm watching when requests have completed by instrumenting a custom SpiceServiceListener to call my custom callbacks implemented within each activity. During onRequestAdded(), I show any Progress UI element. During onRequestSucceeded(), onRequestFailed(), and onRequestCancelled(), I check getSpiceManager().getPendingRequestCount() to see if it reaches zero and then hide any Progress UI elements.
The pending request count never reaches zero in my app (at least inside these three methods), but it seems to stop at one. This is true even though I can see from the Retrofit logging that my requests all appear to be completed.
Is the pending request count global or is it specific to the current Activity and its spice manager instance? Is there a better method to watch for all requests finishing within the current activity?
I have an answer. I missed instrumenting onRequestProcessed(), so the number of pending network requests never appeared to reach zero. The pending request count now does reach zero.
I still don't know if the count is global or local to the current activity and its SpiceManager instance, but I'm getting useful results from my new code.