Some device configurations may change during running (for example, horizontal screen layout, keyboard availability, and language ). When such a change occurs, Android restarts the running Activity (onDestroy () method and then calls the onCreate () method ). This restart action is to automatically load alternative resources to your application to adapt your application to new configurations.
In order to correctly execute a restart, it is important that your Activity status is retained in the entire normal life cycle. Android calls onSaveInstanceState () before destroying your Activity () method To save data about the status before the application. Then you can re-Save the application status in the onCreate () method or onRestoreInstanceState () method. In order to test your application, you can use the application status to restart yourself, you should authorize your application that the application configuration can be changed when the program executes different tasks (for example, the screen direction changes ).
To handle some events, for example, when a user receives a incoming call and returns it to your application, without losing user data or status information, your application should be able to restart itself at any time (for more information, see Activity lifecycle ).
However, you may have to deal with such a situation, restarting your application and re-saving a large amount of valuable data will lead to poor user experience. In the face of such a situation, you have two options:
A maintains an object during configuration change.
When the configuration changes, you can restart your Activity, but let it carry a stateful object to your new Activity instance.
B. Handle configuration changes by yourself.
When some configurations change, the system will be prevented from restarting your Activity and a callback will be received when the configuration changes. In this way, you can manually update your Activity as needed.
Maintain an object during configuration change
If you restart your Activity, you need to restore a large amount of data, re-execute the network connection, or perform other in-depth operations, in this way, a full startup caused by configuration changes will lead to poor user experience. Besides, only the Bundle object stored for you in the Activity life cycle cannot completely maintain the status of your Activity-it cannot pass large objects (such as bitmap objects ), in addition, the data in these objects must be serialized and then deserialized, which consumes a lot of memory to make the configuration change very slowly. In this situation, when your Activity is restarted due to configuration changes, You can reset a stateful object to reduce the burden on your program.
Maintain an object when the configuration changes during running:
1. Override the onRetainNonConfigurationInstance () method to return the object you want to maintain
2. When your Activity is created again, call the getLastNonConfigurationInstance () method to restore your object.
When your Activity is closed due to configuration changes, Android will call the onRetainNonConfigurationInstance () method between the onStop () method and the onDestroy () method. To save the status more effectively after configuration changes, you should return an object you need when implementing the onRetainNonConfigurationInstance () method.
This scenario is valuable when your application needs to download a lot of data from the Internet. If the user changes the device direction and the Activity restarts, your application must reload the data, it will be slow. What you need to do is implement the onRetainNonConfigurationInstance () method and return the object with your data. Then, when your Activity restarts through the getLastNonConfigurationInstance () method, you can get the data. For example:
@ Override
Public Object onRetainNonConfigurationInstance (){
Final MyDataObject data = collectMyLoadedData ();
Return data;
}
Note:When you want to return any object, you should not pass an object associated with the Activity, such as a Drawable object and an Adapter object, A View object or any other Context-related objects. If you do this, it will leak all views and resources of the original Activity instance. (Resource leakage means that your application keeps holding on to them, and they cannot be used as garbage collection, so the memory is lost)
Then, when your Activity restarts, you can get the data:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
if (data == null) {
data = loadMyData();
}
...
}
In this example, getLastNonConfigurationInstance () obtains the data stored in the onRetainNonConfigurationInstance () method. If the data is empty (this happens when the Activity is restarted for another reason rather than due to configuration changes), the program loads data objects from the original data source.
Handle configuration changes by yourself
If your application does not need to update resources during a special configuration change, and you have an operation restriction, you must avoid restarting the Activity, you can declare your own Activity to handle configuration changes and prevent the system from restarting your Activity.
Note:Selecting your own to handle configuration changes will make it more difficult to use alternative resources, because the system will not automatically call these resources for you. This technology should be considered the final means and is not recommended for most applications.
To declare your Activity to handle configuration changes, edit the correct <activity> element in the configuration file, including the android: configChanges attribute with the assigned value, which indicates the configuration you want to process. Android: all possible values of the configChanges attribute should be listed in the document (the most common value is orientation to handle keyboardHidden to handle keyboard availability changes when the screen direction changes ). You can declare the values of multiple configurations in the attribute and separate them using the "|" symbol.
For example, the following list snippet declares that the Activity will simultaneously handle screen direction changes and keyboard availability changes:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
When one of these configurations changes, MyActivity will not be restarted. Instead, this Activity receives calls from the onConfigurationChanged () method. This method transmits a Configuration object to identify the new device Configuration. By reading the configuration field, you can determine the new configuration information and update the resources used in your interface to correctly apply these changes. This method is called at any time. The Resources object of your Activity will be updated and a resource object based on the new configuration will be returned, therefore, you can easily reset your UI elements without restarting your Activity.
For example, the following onConfigurationChanged () method checks the availability of the hardware keyboard and the direction of the current device:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
// Checks whether a hardware keyboard is available
if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
} else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
}
}
This Configuration class object represents all the current Configuration information, not only those changed Configuration information. In many cases, you do not care exactly how these configurations are changed, and you can simply re-allocate all resources to provide alternative resources for the configurations you are processing. For example, because the Resources object is updated now, you can usesetImageResource(int)
Method To reset any ImageView and reset the appropriate resources for the current configuration. (For details, see:
Providing Resources)
Note that the value of the Configuration field is an integer that matches a specific constant in the Configuration class. For the constant used for each field in the document, see the corresponding field in the Configuration class.
Remember:When you declare your Activity to handle configuration changes, you are responsible for resetting all the elements that provide alternative resources. If you declare your Activity to handle changes in the screen direction and have an image that switches between the horizontal and vertical directions, you must re-specify a resource for each element in the onConfigurationChanged () method.
If you do not need to update your program based on configuration changes, you do not need to implement the onConfigurationChanged () method. In this case, all resources used before the configuration change will still be used, and you only need to avoid restarting your Activity. However, your application should always be able to be closed and restarted from its previous status. This is not only because there are some configuration changes that you cannot prevent from restarting your application, but also to handle some events, such as when the user receives a call and then returns to the application.
For more information about Configuration changes, see the android: configChanges document and Configuration class.
Welcome to reprint, reprint please indicate the source of http://www.cnblogs.com/CodeGuy/