Activity Restart on Rotation Android

Activity restart on rotation Android

Using the Application Class

Depending on what you're doing in your initialization you could consider creating a new class that extends Application and moving your initialization code into an overridden onCreate method within that class.

public class MyApplicationClass extends Application {
@Override
public void onCreate() {
super.onCreate();
// TODO Put your application initialization code here.
}
}

The onCreate in the application class is only called when the entire application is created, so the Activity restarts on orientation or keyboard visibility changes won't trigger it.

It's good practice to expose the instance of this class as a singleton and exposing the application variables you're initializing using getters and setters.

NOTE: You'll need to specify the name of your new Application class in the manifest for it to be registered and used:

<application
android:name="com.you.yourapp.MyApplicationClass"

Reacting to Configuration Changes [UPDATE: this is deprecated since API 13; see the recommended alternative]

As a further alternative, you can have your application listen for events that would cause a restart – like orientation and keyboard visibility changes – and handle them within your Activity.

Start by adding the android:configChanges node to your Activity's manifest node

 <activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">

or for Android 3.2 (API level 13) and newer:

<activity android:name=".MyActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name">

Then within the Activity override the onConfigurationChanged method and call setContentView to force the GUI layout to be re-done in the new orientation.

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.myLayout);
}

Android App orientation change restarts activity

Actually you shouldn't prevent the Activity to be restarted. It is neccessary to recreate the Activity after a rotation change for several reasons. One of it is that the layout has to be inflated to deal with the changed screen size and things like that (it's easy to imagine that the layout is totally different in portrait than it is in landscape mode).
However, there is a way you can tell the system that you deal with the screen changes by yourself. Therefore change the line in your manifest

android:configChanges="orientation|keyboardHidden"

to

android:configChanges="orientation|screenSize"

The activity won't be recreated then. You'll get a callback via the onConfigurationChanged() method so you can do something when the orientation has changed. If you don't want to do anything when the configuration has changed, just don't override the onConfigurationMethod() in your Activity. Read this section in the Android Developers API Guide for more information.

I got this from this answer. There are two more approaches in the answer but I think the one I described above is the best in your case.

EDIT: Maybe you have to add keyboard|keyboardHidden to the android:configChanges attribute as well, as stated in this answer


EDIT #2: If you want to retrieve the current orientation of the device you can call

Activity.getResources().getConfiguration().orientation

which will return the constants ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE.

If you're interested in the exact rotation angle, use

int rotation =  getWindowManager().getDefaultDisplay().getRotation();

and implement a differentiation with something like a switch case described here.

And a third way to determine the device's rotation is getRequestedOrientation() which will return a constant defined in the documentation

Does screen rotation make an activity restart on newer Android versions?

The reason is because starting from Android 9, users need to press a new "rotation" button in the navigation bar when screen rotation happens. If you do not press it, the activity will not be destroyed and recreated. Please see this doc for more details.

prevent activity restarting when orientation changes

Write this code in your activity

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.landscapeView);

} else {
setContentView(R.layout.portraitView);
}
}

And also add this line in your Manifest file

android:configChanges="orientation|keyboardHidden|screenSize"

So this will handle both things, it will not restart your activity and will load the layout as per your orientation changes.

android activity restarted when orientation changes

I think this will work.........

<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">

Beginning with Android 3.2 (API level 13), the will "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher you must use

android:configChanges="orientation|screenSize"

Activity restart on rotation change

needs to copy files

what very little people usually realize about Android is that Activity and Fragment is not the place to execute long running operations, such as download stuff from internet or copying files.

Both Activity and Fragment are UI elements which can be destroyed, re-created, without much of a warning.

The correct way of dealing with such an issue is to have a Service to execute the long running operation, the Activity or Fragment should start the service and then immediately "bind" to it, executing the usual unbind and bind again upon rotation.

You can read here about service and bounds services: http://developer.android.com/guide/components/bound-services.html

After the activity (or fragment) is bound to the Service then it can register it self as a listener and the service reports back to it the status/progress of the operation.

On top of it, if the activity disconnects from the service, the service can use the command startForeground to put a notification on the device status bar and keep notifying the user on the operation progress without the need of an activity

I know that way takes a lot more code and is more complex to do. But that is the correct way of doing it.

How to prevent activity to restart after changing its orientation

It really is not recommended to prevent activity restart on config changes.

The recommended ways would either by saving and restoring UI state or by using ViewModel. Either one of them can solve your problem but it's better to use ViewModel approach.



Saving and restoring UI state

Saving state

Right before activity start, but right after config changes have been signaled, override Activity.onSaveInstanceState(Bundle) if you're saving activity state, or `Fragment.onSaveInstanceState(Bundle) if you're saving fragment state.

override fun onSaveInstanceState(outState: Bundle?) {
// Save your data into outState data bundle. And then make sure to
// call the super method.
super.onSaveInstanceState(outState)
}

Restoring state

After activity restart due to config changes, restore the previously saved data
and apply it to the UI.

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ... inflate layout, etc...
if (savedInstanceState != null) {
// If savedInstanceState is not null, that means this activity is restoring from
// config changes. All your saved data in onSaveInstanceState() should be accessible
// from savedInstanceState bundle.
// ... restore values from savedInstanceState and apply to your views ...
} else {
// Initialize vie
}
}


Using ViewModel

This approach is relatively new introduced by Google as part of Android Jetpack library.
Instead of overriding onSaveInstanceState(Bundle) and checking savedInstanceStatefor null, your data is persisted inside aViewModel` and will survive from configuration changes.

Basic

Initialize your data inside the ViewModel and access them from your activity or fragment.

class MyViewModel : ViewModel() {
var myList: List<User> = emptyList()
var currentTabIndex: Int = 0

init {
// Initialize your data here...
}
}
class MyFragment : Fragment() {
private val model by viewModels<MyViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ... inflate layout, etc...
viewPager.setCurrentItem(model.currentTabIndex, false)
// Fetch the values from `ViewModel` and apply to your fragment.
}
}

More about ViewModel

For better usage of ViewModel, it's better to learn from the official comprehensive guide.



Related Topics



Leave a reply



Submit