How can we deal with orientation changes, Activities
/Fragments
stoping / resuming using Volley
?
I know that for GET
requests, the response will be cached and the second time we attempt to make that request, we will get a cached response.(IF the server sends the proper HTTP headers)
But what about POST
? Suppose I make a POST
requests (i.e. register, which I want to happen only once), my app goes to background, request is finished while app is still in background, and then I go back to the app. How do I get the Response
for that Request
, or how do I re-connect to it, if it still pending?
AFAIK there is pretty much no support for this in Volley
. Am I right? Is there an easy way to solve the above mentioned scenario, using Volley
?
Volley doesn't provide a mechanism for this out of the box, but you can look into Square's Otto library for Android, it is made to handle situations like yours elegantly.
Implement the Listener for the Volley request so that it posts a successful response onto the Bus, wrapped in an event object like "RegisterEventSuccess" (you define this yourself). Let your Activities or Fragments subscribe to this event type with Otto's @Subscribe mechanism. If - for example - one Activity launches the Volley request and dies because of a screen orientation change, another Activity instance (also registered to the Otto bus) can then receive the event that contains the response of the Volley request.
Hope this was useful.
I have now attempted to address the concern of @kyle-ivey in that responses arriving in between onPause()
and onResume()
are discarded. This is a real issue as I have experienced it in a live application.
My approach builds on the event bus pattern implemented in the answer by Thomas Moerman, although I've reimpemented an example application from scratch. It depends on the Otto Event bus Library, Gson and Volley. It is implemented in IntelliJ 13 Ultimate using Maven tom resolve the dependencies.
Solution: I add to the previous answers a class which acts as a HTTP Response Buffer which takes over the responsibility of listening to events while the Activity is transitioning. When done, the activity actively polls for any responses that may have arrived while the activity was disconnected to the event bus. It hooks on/off in the onPause
and onResume
-events next to the event-bus registering in a fashion like this:
@Override
protected void onPause() {
super.onPause();
ServiceLocator.ResponseBuffer.startSaving(); // The buffer takes over
ServiceLocator.EventBus.unregister(this); // Unregistering with Otto
}
@Override
protected void onResume() {
ServiceLocator.EventBus.register(this); // Re-registering
ServiceLocator.ResponseBuffer.stopAndProcess(); // Process any responses buffered
}
Here is the implementation of the ResponseBuffer-class.
Caveat 1: If the activity is never resumed, and neither stopAndProcess()
nor stopAndPurge()
is called in any future activity, the buffer may be a source of memory leak. Be aware of how you use it. A safe pattern would be to have stopAndProcess()
in onResume()
in all of your activites.
Caveat 2: It is not thread-safe. If there is to come a context switch on the line between where it stars saving and it unregisters the event bus, it may receive the event twice or zero times.
The example includes some test code in the form of UI and support classes, but the main classes you would need if you want to utilize this pattern in a separate projects are the ones in the following packages:
See the github-repository OttoVolleyDoneRight for a complete example with UI for testing.
There's a simple solution that solved my problem with downloading data from network using Volley library. If your app uses fragments due to Google's recomendations, than everything you should do to prevent crashing if user rotates the screen while loading data is put setRetainInstance(true);
in onCreateView
method of your fragment(-s).
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View theView = inflater.inflate(R.layout.fragment_studios, container, false);
setRetainInstance(true);
lvStudios = (ListView) theView.findViewById(R.id.lvStudios);
return theView;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With