18

I read up on how Android handles "configuration changes" - by destroying the active Activity.

I really want to know from Android Team why this is. I would appreciate an explanation on how the reasoning went, because I don't understand it. The fact that it acts in that way puts us all, as I see it, in a world of pain.

Let's assume you have a Activity which presents a number of EditText:s, checkboxes etc. If a User starts to fill that form with text/data and then changes orientation (or get a Phonecall), then all input the User made is gone. I haven't found any way to preserve state. That forces us to make extremely painful coding to not lose all data.

As I see it, you need another "non-Activity" class (or "value-holding" class perhaps) that has one field for each "form element" (EditText, checkbox etc).

For every single "form element" that exists, you then need to attach an Event like "onChanged" (or onTextChanged or something like that) that updates the corresponding field in the "value-holding" class to make sure that for every single character you type (in a EditText for example) is saved at once.

Perhaps you can use some listener (like "onDestroy" or something) and then fill the value-holding class with data.

I have also found this piece of info where they talk about using Bundle, onSaveInstanceState and onRestoreInstanceState, but that also mean that the programmer has to manually save and then later put back the values in the correct place? This approach is a bit less messier than my suggestions above, but still not very nice.

Am I totally wrong and that this is not how it works, and that I totally missed some vital information?

halfer
  • 19,824
  • 17
  • 99
  • 186
Ted
  • 19,727
  • 35
  • 96
  • 154
  • 1
    The framework automatically handles saving and restoring some of the state; the rest you have to do yourself in methods like `onPause` and `onResume`. I know it's hard to get your head around at first, but you really need to know the lifecycle of an Activity: http://developer.android.com/guide/topics/fundamentals.html#actlife Configuration changes like screen rotation need to start over because they have to completely re-layout the screen. I'm sure someone else will come along and leave a proper answer too. :) – Christopher Orr Jan 09 '10 at 02:59
  • The top answer in the previous question you linked to sums it up pretty well. Easiest way to see what is or isn't saved during rotation or a phone call etc is to try it in the emulator! – Christopher Orr Jan 09 '10 at 03:03
  • 1
    I dont get why re-layout has anything do to with the data contained in the Views. The Android Team - and everyone else - is always talking on how important it is with separation of GUI and code. So why not just redraw the thing, and keep the data? There is one such suggestion here: http://stackoverflow.com/questions/456211/activity-restart-on-rotation-android He suggest to override the onConfigurationChanged and then only do the setContentView, skipping the onCreate... – Ted Jan 09 '10 at 03:04

4 Answers4

12

You should read the Application Fundamentals (specifically, Activity lifecycle). Since Activitys must be able to handle being killed at any time due to memory contraints, etc. it's just a cleaner way to handle rotations without adding too much complexity - instead of checking every resource for an alternate resource, re-structuring the layout, etc. you just save your essential data, kill the activity, re-create it, and load the data back in (if you're willing to deal with the extra complexity of managing this yourself, you can use onConfigurationChanged to handle the configuration change yourself.) This also encourages better practices - developers have to be prepared for their Activity to be killed for orientation change, which has the (good) consequence of being prepared for being killed off by memory contraints also.

Isaac Waller
  • 32,709
  • 29
  • 96
  • 107
  • 1
    Thx for the answer =) The next logical question is why Android restrict memory to 16MB or 32MB... Its 2010, time to realize we're not in the 80ies anymore =) Im curious as to why the Windows Mobile devices (and they have their problems too, I know) dont complain over memory. I can run a lot of stuff there, no problem. But on Android they seem to be hyper-sensitive on using RAM... ? – Ted Jan 09 '10 at 03:34
  • 2
    Memory size is limited as well as memory *bandwidth* on mobile devices. 16MB is a lot to work with. Note that your application is very unlikely to be killed as soon as you launch another app (or five), but you should always be prepared for it -- it's the developer's job to ensure that the user doesn't even know that their app has been killed and restarted when they return to where they left off -- that's what the Android framework affords and encourages. – Christopher Orr Jan 09 '10 at 12:36
  • yes, I understand that. But again, why can for example Windows Mobile devices acts as "a normal" application, ie it does not go around destroying an applications parts "ad hoc". WinMobile can do it, and that is almost the same hardware as on Android-devices. No difference. So complaining on RAM-amount and speed doesnt really hold up in my opinion... – Ted Jan 09 '10 at 13:51
  • 1
    Probably most operating systems, including Windows Mobile can kill off applications too if low on memory, as far as I recall. WM apps are monolithic processes, they aren't split into multiple Activities, Services, ContentProviders and so on. So Android can be cleanly shut down in parts (e.g. taking an Activity out of memory, but keeping a Service running) to free up resources. – Christopher Orr Jan 09 '10 at 16:45
  • On Windows Mobile, apps aren't killed except in extreme situations, but your phone is slowed down the more apps you have open, and you have to manually close apps to free up memory. On Android, it's all done for you. – Isaac Waller Jan 09 '10 at 18:01
4

The contents of an EditText will be saved for you automatically when rotating the screen if you put an android:id attribute on it. Similarly, if you display dialogs using Activity#showDialog, then the dialogs are reshown for you after rotating.

Lance Nanek
  • 6,377
  • 2
  • 24
  • 19
  • 1
    Ehm, I dont think so. I have an ID on it, its android:id="@+id/EditText01" and that doesnt make it auto-save... – Ted Jan 09 '10 at 04:26
  • 2
    The default behavior of saving the state of views with ids is documented here: http://developer.android.com/intl/fr/reference/android/app/Activity.html#onSaveInstanceState%28android.os.Bundle%29 I've also seen it work in practice. If you aren't seeing this behavior, then you are blocking it in some way. For example, if you override onCreate or onRestoreInstanceState and don't call the super method with the provided bundle, or override onSaveInstanceState and don't call the super method to add to the bundle. – Lance Nanek Jan 09 '10 at 18:38
  • I can confirm the described behaviour, screen state being restored after rotation, on a physical Android 1.6 device (Xperia X10), however on the Android 1.6 emulator that I'm using, screen state is lost when I emulate rotation with ctrl-F11. – user77115 May 28 '10 at 10:27
  • I was able to reproduce this behavior by adding an ID to my field. Data was retained (or repopulated) in my EditText when I added an ID. – Slobaum Sep 01 '10 at 14:30
3

on why part - short answer - because you might have resources that needed to be changed as you've rotated the phone. ( Images, layout might be different, etc )

On save - you can save you stuff to bundle and read it back.

  @Override
    protected void onSaveInstanceState(Bundle outState) {

            String story_id = "123"
            outState.putString(ContentUtils.STORYID, story_id);

    }

or you can use onRetainNonConfigurationInstance () as described here http://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance()

Finally if you don't have anything you want to handle during rotation - you can ignore it by putting this into your activity in manifest

android:configChanges="keyboardHidden|orientation"

In general, i would read trough article from url above couple of times, until lifecycle is crystal clear.

Alex Volovoy
  • 67,778
  • 13
  • 73
  • 54
  • 1
    Thx =) Well, as I commented above: they dont separate layout/GUI from data. If the LAYOUT needs to redraw, they just scrap the whole thing. Thats just not OK =) Do the redraw by all means, but keep the data - separate GUI from DATA. They usually state that themselves, but now they ignore it? – Ted Jan 09 '10 at 03:10
  • Well if you have nothing res wise that has to be changed - skip orientation change. If you do - put it in the class with onRetainNonConfigurationInstance. Also, i'm not recommending it - but you can ignore change in manifest, and then on onConfigurationChanged handle it yourself – Alex Volovoy Jan 09 '10 at 03:18
0

@Alex's approach above pointed me to a really, really useful solution when using fragments:

Fragments usually get recreated on configuration change. If you don't wish this to happen, use

setRetainInstance(true); in the Fragment's constructor(s)

This will cause fragments to be retained during configuration change.

http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)

Abdo
  • 13,549
  • 10
  • 79
  • 98