Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Volley - orientation changes

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?

like image 294
Ovidiu Latcu Avatar asked Jun 20 '13 16:06

Ovidiu Latcu


3 Answers

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.

like image 195
Thomas Moerman Avatar answered Nov 20 '22 09:11

Thomas Moerman


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:

  • nilzor.ottovolley.core
  • nilzor.ottovolley.messages

See the github-repository OttoVolleyDoneRight for a complete example with UI for testing.

like image 36
Nilzor Avatar answered Nov 20 '22 10:11

Nilzor


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;
}
like image 1
Volodymyr Shalashenko Avatar answered Nov 20 '22 11:11

Volodymyr Shalashenko