You may not receive data, for example, in the event of a server error. This will be an even more bizarre behavior for the user, since the data disappeared after the turn.<\/li><\/ul>\n\n\n\nSo how do you deal with it? And why did such a problem arise with such an innocent act?<\/p>\n\n\n\n
To answer the question about why such a problem arose is quite difficult. Obviously, it was necessary to destroy all data when changing the configuration, so as not to show the user an incorrect state. But there was certainly a way that would reduce the number of such problems, but it was probably too difficult for the first versions of Android, and now it is necessary to maintain backward compatibility.<\/p>\n\n\n
[wpanchor id=»1″]<\/p>\n\n\n\n
If you can not do anything with this situation, then you have to get used to such conditions. In fact, there are many ways how to correctly save and restore data when recreating Activity. Consider them.<\/p>\n\n\n\n
Prohibition of change of orientation<\/h3>\n\n\n\n
Of course, the most common reason for recreating Activity due to configuration changes is the orientation change. Therefore, quite a lot of developers, not wanting to deal with all the problems related to the processing of the life cycle, rigidly fix the orientation and do not think about this problem any further. Such fixation is achieved by adding a flag in the manifest:<\/p>\n\n\n\n
<activity\n\n android:name=\".WeatherActivity\"\n\n android:screenOrientation=\"portrait\"\/><\/pre>\n\n\n[wpanchor id=»2″]<\/p>\n\n\n\n
Of course, this approach simplifies a lot, but it is not always acceptable. In principle, there are many applications that only portrait orientation is sufficient for, but this is more an exception than the rule. Often users work in landscape orientation (especially on tablets) and make them change it for the sake of your application is not very good. And everything else you need to understand that fixed orientation does not save you from problems with recreating Activity, because there are other reasons for this, and not just a change of orientation. Therefore, such a decision can not be considered ideal.\n<\/p>\n\n\n\n
Self-processing<\/h3>\n\n\n\n
In addition, you can not prevent changing any configuration (for example, orientation), but to process it yourself. To do this, you must specify a flag in the manifest with the appropriate value:<\/p>\n\n\n\n
<activity\n\n android:name=\".WeatherActivity\"\n\n android:configChanges=\"orientation|keyboardHidden|screenSize\"\/>\n\n\u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442 Activity \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0442\u0430\u043a\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438 \u043d\u0443\u0436\u043d\u043e \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u0443\u0436\u0438\u0442 \u043c\u0435\u0442\u043e\u0434 onConfigurationChanged \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 Activity:\n\n@Override\n\npublic void onConfigurationChanged(Configuration newConfig) {\n\n super.onConfigurationChanged(newConfig);\n\n \/\/ handle new configuration\n\n}<\/pre>\n\n\n[wpanchor id=»3″]<\/p>\n\n\n\n
In some cases this treatment is not required. But you need to understand that such processing is also fraught with consequences, since the system does not automatically apply alternative resources (and this applies not only to linguistic resources, but also to the usual layout-land, for example). Therefore, this is a rather rare option, but it must also be borne in mind.\n<\/p>\n\n\n\n
Saving state to Bundle<\/h3>\n\n\n\n
Android provides us with a way to save the state and then restore it when you recreate Activity. Here it is worth paying attention to the parameter savedInstanceState, which is passed in the onCreate method in Activity. This instance of the Bundle class is not simply passed on, it can store various fields in it that will be written to it. The first time you start Activity, this parameter will always be null. If you recreate Activity, it will no longer be null, so you can track whether the first Activity is started or whether it is a call after the re-creation, which is very convenient. And now the main thing is that you can save your fields in the Bundle method in the onSaveInstanceState method in the Activity class in approximately the following way:<\/p>\n\n\n\n
@Override\n\nprotected void onSaveInstanceState(Bundle outState) {\n\n super.onSaveInstanceState(outState);\n\n outState.putSerializable(WEATHER_KEY, mCity);\n\n}<\/pre>\n\n\n\nAnd this object of class Bundle, in which you saved some values, after the re-creation will get as a parameter in the onCreate method, and from there you can extract all the data. With this approach, the code for processing the screen state change looks like this:<\/p>\n\n\n\n
@Override\n\nprotected void onCreate(Bundle savedInstanceState) {\n\n super.onCreate(savedInstanceState);\n\n setContentView(R.layout.activity_weather);\n\n if (savedInstanceState == null) {\n\n loadWeather();\n\n } else {\n\n mCity = (City) savedInstanceState.getSerializable(WEATHER_KEY);\n\n showWeather();\n\n }\n\n}<\/pre>\n\n\n\nThat is, we check if the Activity is started for the first time (the phrase «for the first time» here is not very suitable, because the Activity can run several times, but here it is understood that the launch is not after re-creation), then we start to download weather information. If Activity is re-created, then we save weather information in the onSaveInstanceState method, and restore it in the onCreate method.<\/p>\n\n\n\n
Here you need to notice an important fact — not always the weather will be loaded before Activity is recreated. Therefore, the code above should be slightly modified:<\/p>\n\n\n\n
@Override\n\nprotected void onCreate(Bundle savedInstanceState) {\n\n super.onCreate(savedInstanceState);\n\n setContentView(R.layout.activity_weather);\n\n if (savedInstanceState == null || !savedInstanceState.containsKey(WEATHER_KEY)) {\n\n loadWeather();\n\n } else {\n\n mCity = (City) savedInstanceState.getSerializable(WEATHER_KEY);\n\n showWeather();\n\n }\n\n}\n\n\n\n@Override\n\nprotected void onSaveInstanceState(Bundle outState) {\n\n super.onSaveInstanceState(outState);\n\n if (mCity != null) {\n\n outState.putSerializable(WEATHER_KEY, mCity);\n\n }\n\n}<\/pre>\n\n\n[wpanchor id=»4″]<\/p>\n\n\n\n
It’s possible that this method is not so convenient, but it works well when you have to save small data on one single screen. But you need to take into account that you can not save large objects or huge amounts of data in this way, as their serialization and recovery takes a long time, and because of this the application will work slowly.\n<\/p>\n\n\n\n