Why not use always android:configChanges="keyboardHidden|orientation"?
Asked Answered
G

4

194

I was wondering why not use android:configChanges="keyboardHidden|orientation" in every (almost every ;)) activity?

Goods:

  • no need to worry about your activity been rotated
  • it's faster

Not so nice:

  • need to change your layouts if they are depending on screen size (e.g. layouts with two columns or so)

Bad:

  • no flexible way to have different layouts on different orientation
  • not so good when using fragments

But if we don't use different layouts, why not?

Gabriellia answered 19/10, 2011 at 8:45 Comment(4)
You should also explain what you think keyboardHidden|orientation is doingEnameling
It's preventing from using native handling of specified configuration changes and allowing application to handle it, isn't it?Gabriellia
That's why this option is there, if you know what you're doing (no changes in resources), use it.Surveyor
why is it faster than using ScreenSize ?Timeout
S
352

Quick Background

By default, when certain key configuration changes happen on Android (a common example is an orientation change), Android fully restarts the running Activity to help it adjust to such changes.

When you define android:configChanges="keyboardHidden|orientation" in your AndroidManifest, you are telling Android: "Please don't do the default reset when the keyboard is pulled out, or the phone is rotated; I want to handle this myself. Yes, I know what I'm doing"

Is this a good thing? We shall soon see...

No worries?

One of the pros you start with is that there is:

no need to worry about your activity been rotated

In many cases, people mistakenly believe that when they have an error that is being generated by an orientation change ("rotation"), they can simply fix it by putting in android:configChanges="keyboardHidden|orientation".

However, android:configChanges="keyboardHidden|orientation" is nothing more than a bandaid. In truth, there are many ways a configuration change can be triggered. For example, if the user selects a new language (i.e. the locale has changed), your activity will be restarted in the same way it does by an orientation change. If you want you can view a list of all the different types of config changes.

Edit: More importantly, though, as hackbod points out in the comments, your activity will also be restarted when your app is in the background and Android decides to free up some memory by killing it. When the user comes back to your app, Android will attempt to restart the activity in the same way it does if there was some other configuration change. If you can't handle that - the user will not be happy...

In other words, using android:configChanges="keyboardHidden|orientation" is not a solution for your "worries." The right way is to code your activities so that they are happy with any restart Android throws at them. This is a good practice that will help you down the road, so get used to it.

So when should I use it?

As you mentioned there is a distinct advantage. Overwriting the default configuration change for a rotation by handling it yourself will speed things up. However, this speed does come with a price of convenience.

To put it simply, if you use the same layout for both portrait and landscape you're in good shape by doing the overwrite. Instead of a full-blown reload of the activity, the views will simply shift around to fill the remaining space.

However, if for some reason you use a different layout when the device is in landscape, the fact that Android reloads your Activity is good because it will then load up the correct layout. [If you use the override on such an Activity, and want to do some magical re-layout at runtime... well, good luck - it's far from simple]

Quick Summary

By all means, if android:configChanges="keyboardHidden|orientation" is right for you, then use it. But PLEASE be sure to test what happens when something changes, because an orientation change is not the only way a full Activity restart can be triggered.

Strasbourg answered 3/11, 2011 at 5:9 Comment(14)
It is worth adding that not handling your activity being restarted means you have bigger problems than just not handling less common config changes. The activity restart used here is the exact same mechanism as how Android restores your activity to its previous state when your app gets killed in the background. So if you aren't doing this correctly, your users will experience your app randomly not coming back correctly when they return to it from the background, depending on whether the process happened to be killed. So a huge benefit: it makes sure your app correctly restarts.Pepperandsalt
From Android 3.x on don't miss to add "screenSize" ---------- android:configChanges=["mcc", "mnc", "locale", "touchscreen", "keyboard", "keyboardHidden", "navigation", "screenLayout", "fontScale", "uiMode", "orientation", "screenSize", "smallestScreenSize"]Doralynn
I've noticed that when you use the configChanges attribute, your app also ignores the orientation-lock feature. How can you solve this? if you know the answer, please write it here: #24000861Animality
Please don't do the default reset when the keyboard is pulled out i have never seen an Activity restart for Keyboard pull out!Munos
well occasional restarts are ok in my opinion... configChanges handles most cases for me... well maybe in some other type in applications this can be problem but it depends really....Reviel
Does order of configChange parameters matters ??Scabble
@vinaykumar It shouldn't.Strasbourg
This answer sadly doesn't mention the main explanation from official Google documentation. The main problem is in alternative resource sets, which do not get applied for you automatically on configuration change, should you want to handle it manually. And it affects not only the Activity in question but the whole application.Taps
totally wrong answer. First, activity doesn't reset when keyboard is pull out. Second, when android wants to free memory it kills process, not activity.Grobe
its worth to give it a read and then check. Really helpful :)Santos
To be honest, make your app restartable - cost a lot in terms of code complexity and lines of it. But it get very little benefit. Modern devices has a lot of memory, so your activity will never be killed at freeing memory. Likely your whole app will be killed. You write 30% of code to work properly in 0.01 percent of cases.Gide
@PavelShorokhov I don't think that your opinion is correct. Activity can be restarted anytime because of configuration changes, not only because the memory is low. Google emphasized us to support configuration change. This is going more and more emphasized, especially after Android 7.0 because of developer.android.com/guide/topics/ui/multi-window. More and more devices can easily switch the window size (i.e., Foldable phones, Samsung Dex Mode). Suppose you keep the Activities as non-restartable. Your application will misbehave on those devices.Wellfound
@Wellfound with android:configChanges="screenSize" you can prevent recreate activity in this case. So this will not be problem, your view will be resized but not recreated. Actually, if you see on flutter, it has all possible configChanges in this property. I don't want to say that this is right and you should do so. But sometimes (in many cases) it can be more preferable approach. So I believe it shouldn't be banned or marked as bad practice.Gide
@PavelShorokhov That is correct. There is no reason that you can't simply define a bunch of overrides for items you want to handle yourself and it certainly should not be banned. The only point is that there may be other items that can cause an activity restart [even some which will be introduced in future Android versions!] - so it's important to make sure the activity can always handle a restart. The problem was that many just use these overrides as a quick "bandaid" fix which can be bad practice.Strasbourg
D
3

From my point of view: If the layout is the same in both landscape and portrait mode - you might aswell disable one of the two in your app.

The reason why I state this is that I as a user expect the app to provide me with some benefit, when I change orientation. If it doesn't matter how I hold my phone, then I don't need the choice.

Take for instance an app where you have a ListView, and upon clicking a ListItem you want to be shown a detailed view for that item. In landscape you would od this by dividing the screen in two, having the ListView on the left and the detailed view on the right. In Portrait you would have the list in one screen and then change the screen to the detailed view when a ListItem is selected. In that case orientation change makes sense as well as different layouts.

Diaz answered 19/10, 2011 at 8:58 Comment(7)
Yeah, we went with that in version 1.0 of our app, to match our Apple release. It was presented ONLY in portrait. Which looked great on my Droid X, we matched the popup keyboard behavior of the IOS version exactly. Then the CFO installed the app on his Droid, turned it to the side and slid the keyboard open. Oops. The thing about Android is it is an open platform and you really can't predict the hardware configuration or what the user will want to do with it, so you should probably support both (all) orientations just in case.Psychodrama
Which incidentally overrode our portrait-only setting since it was basically in the hardware that landscape was then the normal, not alternate, orientation. Which REALLY messed up our layout :( and was pretty embarassing, having a major flaw within seconds of him installing the appPsychodrama
Why were you trying to make it behave exactly like iOS? :(Sodium
@Sodium Unfortunately we live in a world where businessmen make technical decisions. Even if you argue against it, half the time they think they're right anyway. And they control your paycheck.Limicolous
Not sure if I understand you correctly but it's never a good idea to lock the phone to portrait/landscape only since users use their phones in many different ways. Some use their phone in landscape a lot and apps that lock to portrait then becomes unusable.Rajput
Using only one layout does not mean that the screen will look the same when rotated. A well structured XML layout will cause things to automatically shift around to work well in with reasonable dimensions, and users will appreciate that.Tappet
Hi can someone knowledgeable on this topic please have a look at my thread: stackoverflow.com/questions/35941585/… ? Desperately need help.Sinistrodextral
R
-1

I don see why.... occasional restarts are ok in my opinion... configChanges handles most cases for me... well maybe in some types of applications this can be problem but it depends really on type of app and how you restore state when app restarts... When one of my app restarts user is logged back and last activity opens by my code and user jus loses some steps to go back where he was but not big deal.. In other some state is always persisted and some state is always restored on restart. When activity restarted it had to be that app have not been used or something... so no problem at all... In game for example this can be problem maybe or in some other type of app I don't know...

I say that when you do it this way applications just works fine under normal circumstances. And code is much more readable without ton of logic needed for saving and restoring where u just can make new bugs and have to maintain it all the time... sure if android gets out of power and kill you application window it lose the context and starts again, but this happen just in special situations and on newer devices I belive this is more and more rare...

So kill me, but I use this across applications quite successfully... android:configChanges="locale|keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" But I understand that for some special kind of applications it may be not good way but most of apps can live with this just OK.

Reviel answered 7/5, 2015 at 10:45 Comment(4)
Hi can someone knowledgeable on this topic please have a look at my thread: stackoverflow.com/questions/35941585/… ? Desperately need help.Sinistrodextral
You should fully support saving/resuming on activities... handling it for rotation is no different... You say you lose a few steps... if you do it properly you lose no steps and you restore exactly where the user left off... even after restart of device.Charisecharisma
hammered I dont know what you are talking about but I say that when you do it this way applications just works fine under normal circumstances. And code is much more readable without ton of logic needed for saving and restoring where u just can make new bugs and have to maintain it all the time... sure if android gets out of power and kill you application window it lose the context and starts again, but this happen just in special situations and on newer devices I belive this is more and more rare...Reviel
Ignoring to adhere to the Activity contract (saving/restoring state) is bad practice, and this is overall terrible advice. Try testing against process death and see where your app gets you, and this behavior is completely standard "normal circumstance" if your user uses at least 2-3 apps on their phone and switches between them.Probationer
F
-3

Yeah I think pausing will make it quicker than releasing the player. Still have the pause though.

Have now found a solution that won't pause the song.

State in the manifest that you will handle the config change for screen orientation and then use the onConfigurationChanged method to load the layout file. By doing this in logCat I can see onPause, onCreate & onResume aren't called, and therefore the song isn't paused.

  1. update the manifest to handle the orientation.

    android:configChanges="orientation|screenSize"
    
  2. add this code

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub      
        super.onConfigurationChanged(newConfig);        
        setContentView(R.layout.activity_main);
    }
    
Floorer answered 19/1, 2014 at 21:9 Comment(1)
You should be using a service to play music. Seriously, you are telling people to add code that still has " // TODO Auto-generated method stub" in it. Sloppy solution. It won't work nicely either, you'll need to rebind all your references, and if you don't they are going to be unpredictable at best.Charisecharisma

© 2022 - 2024 — McMap. All rights reserved.