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 a
ViewModel` 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
Android Force Gpu Rendering How to Enable and Disable
Imageview of Png Doesn't Appear (Maybe It's Too Big)
How to Control Navigationview Margin Between Menu Items
Notification Disappears After Showing
How to Close the Current Fragment by Using Button Like the Back Button
How to Get Context in Android Mvvm Viewmodel
How to Open Draw Overlay Permission Popup in Miui
How to Keep a Bottom Nav Bar from Being Pushed Up on Keyboard Shown
Adb.Exe Not Found After Installing Android Studio
How to Use Python to Execute Adb Commands
How to Check If a Value Exists Already in a Firebase Data Class Android
How to Go Back to Previous Fragment from Activity
How to Access the Camera from Within a Webview
How to Set the Starting Position of a Scrollview
Flutter:Renderbox Was Not Laid Out: Renderrepaintboundary#58C65 Relayoutboundary=Up1 Needs-Paint
How to Restrict Entry of Numbers But Allow All the Special Characters and Alphabets in Edittext
Edittext Background Base Line Color Changing Based on Its Focus in Android
How to Display a Loading Spinner While Getting Data from Firestore