Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice to handle orientation change: Android

I was going through various practices to handle orientation change with threads and AsyncTask. I came across following solutions:

  1. Attach-detach model : Attaching and detaching activity to threads and AsyncTask while preserving their instance. (Source: 1, 2)

  2. Headless fragment way : Using a non-UI/headless fragment to do all the thread related operations and retaining its instance on configuration change. (Source: 1, 2)

Are there any other approaches to handle this scenario? What is the recommended practice? I'm asking this because I couldn't find a generic solution anywhere in the Android docs.

like image 528
Gaurav Arora Avatar asked Dec 11 '13 09:12

Gaurav Arora


People also ask

What happens when orientation changes Android?

When you rotate your device and the screen changes orientation, Android usually destroys your application's existing Activities and Fragments and recreates them. Android does this so that your application can reload resources based on the new configuration.

What is the effective approach that is used to handle screen orientation?

Lock screen orientation To lock the screen orientation change of any screen (activity) of your android application makes your activity display only in one mode i.e. either Landscape or Portrait. This is the simplest way to handle screen orientation but not generally recommended.

How do you adapt and manage changes in screen orientation?

To switch between portrait mode and landscape mode on the device emulator, press the Ctrl+F11 keys.

How do I stop Android from restarting activity when changing orientations?

If you want the activity to not restart during screen orientation change, you can use the below AndroidManifest. xml. Please note the activity android:configChanges=”orientation|screenSize” attribute. This attribute makes the activity not restart when change screen orientation.


3 Answers

Some summaries

There are several methods mentioned above that are good practices but I thought I might sum them up with short explanations. Below are some of the most popular libraries being used currently for http networking, asynchronous work / threading, and caching.

My current project (just preferences)

I personally am currently using Otto, Loaders, Volley, Ormlite, and a network stack based on Apache and Services. I do hope to replace, the network stack at some point with either Volley, Retrofit, and maybe eventually Robospice.

I personally very much like Otto and Volley


RoboSpice (Modular)

  • https://github.com/octo-online/robospice
  • http://www.youtube.com/watch?v=ONaD1mB8r-A
  • a plugin / modular approach to long-running tasks
  • this is like the "swiss-army-knife" of libraries, but you need to know what each tool does.
  • Handles REST calls
  • persists data through orientation and other changes
  • can handle disk and memory caching )
  • works with various HTTP libraries and persistence libraries (Gson, Jackson, Spring, OkHttp, and many of the below libraries)
  • beta for Ormlite support, I think

Retrofit (REST)

  • https://github.com/square/retrofit
  • Annotation library to make REST very easy. Works with Robospice.

Volley (Networking data & Images)

  • https://android.googlesource.com/platform/frameworks/volley
  • https://developers.google.com/events/io/sessions/325304728
  • This is the networking code that runs the Google Play Store
  • Fast, reliable
  • Handles most caching for you with some sensible defaults
  • very easy to use
  • built specifically for very fast image, json, etc loading
  • Handles all threading for you.

Picasso (images)

  • https://github.com/square/picasso
  • Http library for loading images
  • fast
  • very easy to use

Loaders (Android)

  • well supported
  • persist through orientation change and save/load of fragment state
  • can be difficult to get right
  • no caching

AsyncTask (Android)

  • simple way for background work from the UI thread
  • must be canceled and be careful about tasks that return after an activity or fragment is torn down.

Otto (event bus)

  • https://github.com/square/otto
  • Event bus that makes a-sync work between components and fragments easy
  • Very powerful @Produce ability retains the last event and can produce it on demand for any new interested subscribers to the bus

Headless Fragments (?)

  • I personally have never seen this used other than Vogella's tutorials, so I'm not sure on this one.

Service (Android)

  • The old school way
  • ultimate control, you must do everything yourself
  • usually used with Appache or HURL client and
  • pass Parcels around via Intents
like image 66
pjco Avatar answered Oct 22 '22 09:10

pjco


Why don't you try Loaders, in particular AsyncTaskLoader? They are available for pre-Honeycomb through Support Library and perfectly match Activity/Fragment lifecycle. Here is the official summary:

  • They are available to every Activity and Fragment.
  • They provide asynchronous loading of data.
  • They monitor the source of their data and deliver new results when the content changes.
  • They automatically reconnect to the last loader's cursor when being recreated after a configuration change. Thus, they don't need to re-query their data.
like image 21
a.ch. Avatar answered Oct 22 '22 08:10

a.ch.


We are actually using RoboSpice library. It runs on a Service with only providing RequestListeners objects.

The problem with your first approach (Keeping references between the AsyncTask) is that you can probably generate memory leaks because when your AsyncTasks holds your Activities references, they will be not garbage collected. Keep an eye on this just profiling your application checking Heap Size rotating the same Activity over and over again. Your heap should grow in the normal parameters (There is a moment when your objects that must be garbage collected lives at the same time with new objects) but when GC runs your RAM allocation should fall to the same size that you've allocated at the beginning.

So if I have to recommend something will be the next thing:

Activity managing API Calls and Flows (With RoboSpice, letting de UI rotate) Simple screens inside Fragments using retainInstance in true. This let to you pass your DTOs directly to your fragments, and you have to only manage the state at the top level Activity.

like image 4
noni Avatar answered Oct 22 '22 08:10

noni