Android configuration file (3) ---- root node of the application <application>, androidapplication
<Application> A node is a required node in the AndroidManifest. xml file. It is included in the <manifest> node. Through the <application> node attributes, we can declare the related features of Android applications. This node contains nodes of all application components, including Activity, service, broadcast receiver and content provider, and contains attributes that may affect all components. Some of these attributes are set to the same attributes of application components as the default values, such as icon, label, permission, process, taskAffinity, and allowTaskReparenting, other values are set as the whole of the application, and cannot be overwritten by Attributes of application components, such as debuggable, enabled, description, and allowClearUserData.
1. <application> node configuration
Generally, when an Android application is generated, the default AndroidManifest. xml file contains some default <application> nodes, including the basic attributes of the application. Now let's take a look at the complete set of <application> node information. The Code is as follows:
<Application android: allowTaskReparenting = ["true" | "false"]
Android: backupAgent = "string"
Android: debuggable = ["true" | "false"];
Android: description = "string resource"
Android: enabled = ["true" | "false"]
Android: hasCode = ["true" | "false"]
Android: hardwareAccelerated = ["true" | "false"]
Android: icon = "drawable reource"
Android: killAfterRestore = ["true" | "false"]
Android: label = "string resource"
Android: logo = "drawable resource"
Android: manageSpaceActivity = "string"
Android: name = "string"
Android: permission = "string"
Android: persistent = ["true" | "false"]
Android: process = "string"
Android: restoreAnyVersion = ["true" | "false"]
Android: taskAffinity = "string"
Android: theme = "resource or theme">
</Application>
2. How to Implement the Application class
The first thing to introduce is the android: name attribute, which refers to a subclass of the Application class. When an Application process is started, android: the class specified by the name attribute will be instantiated before all application components (activity, service, broadcast receiver, and content provider) are instantiated.
Generally, the application does not need to specify this attribute. Android will instantiate the applicaiton class in the Android framework.
However, in some special cases, for example, you want to complete initialization before the application component is started, or do some special processing when the system is low in memory, you must consider implementing a subclass of your Application class.
In the system applications provided by the Android system, there is an Application instance that implements its own. This Application is Launcher. We can follow it to implement an Application class. The specific steps are as follows.
① Create a project called ApplicationTest and add a line of code in the onCreate () method of the default MainActivity to output a log. In this way, you can see the Application creation time. The specific code is as follows:
public class MainActivity extends Activity { private static final String TAG="MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e(TAG,"MainActivity is created"); }}
② Implement your own MyApplication class. The Code is as follows:
public class MyApplication extends Application { private static final String TAG="MyApplication"; @Override public void onCreate() { super.onCreate(); Log.e(TAG,"MyApplication is created"); }}
③ Add MyApplication to android: name in the <application> file AndroidManifest. xml in the configuration file
As you can see, Android first creates the MyApplication and then creates the MainActivity.
3. functions provided by Application and their usage
The android. app. Application class provides many methods similar to onCreate (), which are called back by the Android framework in different scenarios. At the same time, the Application class also provides some monitoring functions to monitor the life cycle of components in the Application. See the following table:
Method Name |
Return Value |
Annotation |
OnConfigurationChanged (Configuration newConfig) |
Void |
If the device configuration (including language, direction, and network) changes when the component is running, the system calls this method to notify the application. |
OnCreate () |
Void |
This method is called when an application is started and before any other application object is created. Because the time spent on this function directly affects the speed of starting the first Activity service or receiver in a process, it is executed as quickly as possible (for example, using a slow initialization status ). If you override this method, make sure to call super. onCreated () Note that in actual applications, if some components in your Application specify a process attribute (process) and the process does not exist, the onCreate () callback is called. In other words, this method may be called multiple times. |
OnLowMemory () |
Void |
The system calls this method to notify the application when the system is running with low memory and the application wants to reduce memory usage. However, when the accuracy of this method is not defined, it usually occurs near the time when all background processes have been terminated. Applications can execute this method to release any buffering or unnecessary resources they own. The system returns this method and then runs the garbage collection operation. |
OnTerminate () |
Void |
This method is used in the simulation process environment and is not called on the Production Android device. On the production Android device, you can simply terminate the process to remove the process. No user code (including this callback) is executed during the removal process) |
OnTrimMemory () |
Void |
Called when memory is recycled. For example, when it enters the background and does not have enough memory to keep many background processes running. |
Monitoring callback Interface RegisterComponentCallbacks UnregisterComponentCallbacks |
Void
Void |
Register a ComponentCallbacks interface in the application. Before the Activity lifecycle changes, the application is notified through each method of this interface. With this interface, we can perform some necessary processing before the Activity lifecycle changes. You must note that you must use unregisterComponentCallbacks (ComponentCallbacks) to remove the ComponentCallbacks object as appropriate in the future. It was previously registered with registerComponentCallbacks (ComponentCallbacks. |
Next, we will use some examples to illustrate how to use these methods and interfaces.
① Use the onConfigurationChanged () method to listen for System Configuration updates
The function prototype of the onConfigurationChanged () method is as follows:
Public void onConfigurationChanged (Configuration newConfig) {} Where the newConfig parameter indicates the New Device Configuration
The onConfigurationChanged () method is a callback interface that is called by the Android system when the device configuration changes. At the same time, the Android system will pass the parameter (newConfig) to the application, and the application will handle this change. Note: Unlike Activity, other components are never restarted when a configuration change occurs. Sun weak handles the change results by themselves. The "configuration" described here is shown in the following table:
Configuration item |
Annotation |
FontScale |
Indicates the font scaling ratio of the current system, which is based on pixel density scaling. Note: The system firmware compiled in user mode does not contain the interface for modifying this configuration. It can only be changed through programming. Data Type: Float Type |
HardKeyBoardHidden |
Indicates whether the hard keyboard is hidden. This configuration item has three values, as shown below. 0. HARDKEYBOARDHIDDEN_UNDEFINED (the keyboard status that Android cannot recognize) 1. HARDKEYBOARDHIDDEN_NO (hard keyboard is available) 2. HARDKEYBOARDHIDDEN_YES (hard keyboard hidden) Data Type: integer |
Keyboard |
Indicates the type of keyboard that is added to the device. This configuration item has the following four values: 0. KEYBOARD_UNDEFINED (an unrecognized Android keyboard) 1. KEYBOARD_NOKEYS (keyless keyboard) 2. KEYBOARD_QWERTY (typewriter keyboard) 3. KEYBOARD_12KEY (12-key keyboard) Data Type: integer |
KeyboardHidden |
Indicates whether the current keyboard is available. If a hard keyboard is hidden from an Android device with a hard keyboard, the keyboard is considered available. This field has the following three values. 0. KEYBOARDHIDDEN_UNDEFINED (the keyboard status that Android cannot recognize) 1. KEYBOARDHIDDEN_NO (the keyboard is still visible) 2. KEYBOARDHIDDEN_YES (all keyboards are hidden ). Data Type: integer |
Locale |
Defines the language environment of the device. It contains country and language information, which is contained in a java. util. Locale type object. |
Mcc |
IMSI's mobile Country Code. If it is 0, it indicates no definition. Note: IMSI is an international mobile user identification code. It is stored in our SIM card and has a total length of no more than 15 characters. Data Type: integer |
Mnc |
IMSI mobile network number. If it is 0, it indicates no definition. Data Type: integer |
Navigation |
Indicates the available navigation method of the current device. It has the following five values. 0. NAVIGATION_UNDEFINED (undefined navigation method) 1. NAVIGATION_NONAV (no navigation) 2. NAVIGATION_DPAD (Panel Navigation Mode) 3. NAVIGATION_TRACKBALL (trackball navigation) 4. NAVIGATION_WHEEL (scroll navigation) Data Type: integer |
NavigationHidden |
Used to indicate whether the navigation is available. The value is as follows. 0. NAVIGATIONHIDDEN_UNDEFINED 1. NAVIGATIONHIDDEN_NO 2. NAVIGATIONHIDDEN_YES Data Type: integer |
Orientation |
The four values that indicate the screen direction. 0. ORIENTATION_UNDEFINED (undefined method) 1. ORIENTATION_PORTRAIT (portrait orientation, screen width less than height) 2. ORIENTATION_LANDSCAPE (horizontal screen direction, screen width greater than height) 3. ORIENTATION_SQUARE (square screen, think the screen width is equal to the height) Note: When the new configuration is calculated in Windows Management Service, the default configuration of orientation is ORIENTATION_SQUARE. Data Type: integer |
ScreenHeightDp |
Height of available part of the screen |
ScreenLayout |
Indicates the overall properties of the screen, which consists of two parts. ⒈ SCREENAYOUT_SIZE_MASK: Specifies the screen size attributes (such as large screen and small screen). It has the following five values. SCREENAYOUT_SIZE_UNDEFINED: Undefined (value: 0) SCREENAYOUT_SIZE_SMALL: small screen (value: 1, the screen resolution is at least 320*426 ). SCREENAYOUT_SIZE_NORMAL: normal screen (value: 2, screen resolution at least 320*470) SCREENAYOUT_SIZE_LARGE: Large Screen (value: 3, screen resolution at least 480*640) SCREENAYOUT_SIZE_XLARGE: Add a large screen (value: 4, the screen resolution is at least 720*960) ⒉ SCREENAYOUT_LONG_MASK: indicates whether the screen is higher or wider than usual. It has three values. SCREENAYOUT_LONG_UNDEFINED: Undefined (The hexadecimal value is 0) SCREENAYOUT_LONG_YES: Yes (The hexadecimal value is 20) SCREENAYOUT_LONG_NO: No (The hexadecimal value is 10) |
ScreenWidthDp |
Width of the available part of the screen |
SmallestScreenWidthDp |
In normal operation, the application will see the minimum screen size. This is the minimum value of screenWidthDp and ScreenHeightDp in the portrait and landscape screens. |
Touchscreen |
The type of touch screen on the device. The following values are supported. 0. TOUCHSCREEN_UNDEFINED (undefined Mode) 1. TOUCHSCREEN_NOTOUCH (no touch screen mode) 2. TOUCHSCREEN_STYLUS (handwriting Mode) 3. TOUCHSCREEN_FINGER (finger touch screen mode) |
UiMode |
The bitmask of the UI mode. Currently, there are two fields. Define UI_MODE_TYPE_MASK: defines the entire UI mode of the device. It supports the following values. UI_MODE_TYPE_UNDEFINED: Unknown Mode UI_MODE_TYPE_NORMAL: Normal Mode UI_MODE_TYPE_DESK: with base mode' UI_MODE_TYPE_CAR: In-Vehicle Mode Define UI_MODE_NIGHT_MASK: defines whether the screen is in a special mode. It supports the following values. UI_MODE_NIGHT_UNDEFINED: the mode is not defined. UI_MODE_NIGHT_NO: Non-night mode UI_MODE_NIGHT_YES: Night mode |
The following example shows how the system notifies the application through the onConfigurationChanged callback interface when the device configuration changes.
(I) Add a subclass of Application named ConfigApplication to the previous Application and implement the onCreate () method and onConfigurationChanged () method. In the onCreate () method, we obtain the configuration information of the application at the beginning of creation. In the onConfigurationChanged () method, you can add some code to reflect Configuration updates in real time using logs. The related code is as follows:
Public class ConfigApplication extends Application {private static final String TAG = "ConfigApplication"; private Configuration mConfiguration; @ Override public void onCreate () {super. onCreate (); this. mConfiguration = getResources (). getConfiguration (); // get the configuration Log. e (TAG, "onCreate: infomation: orientation =" + this. mConfiguration. orientation) ;}@ Override public void onConfigurationChanged (Configuration newConfig) {super. onConfigurationChanged (newConfig); // print the updated configuration Log. e (TAG, "onConfigurationChanged: infomation: orientation =" + newConfig. orientation );}}
(Ii) Configure ConfigApplication to the AndroidManifest. xml file as described above.
(3) When the device runs the application, the following log information is displayed.
Logs are described as follows:
The first line of log information is the direction configuration in the initial state. We know that the initial direction value is 1. According to the preceding table, we can see that the current direction is portrait.
The fifth line of the log information is the onConfigurationChanged () method called back by the Android system after switching the landscape screen. At this time, the system configuration has changed, therefore, the log here prints the current screen direction 2, which is also horizontal screen.
Suggestion: Because the base class onConfigurationChanged () method implements call to some callback interfaces, If we override this method, in order to maintain the behavior of the original Application class, we recommend that you call super at the rewrite method entry. onConfigurationChanged (newConfig ).
② Use onCreate () to initialize the application
The onCreate () method is prototype:
Public void onCreate (){}
As shown in the preceding table, the onCreate () method is a callback interface. The Android system calls this interface before any application components (Activity, service, broadcast receiver, and content provider) are created when the application is started.
It should be noted that the execution efficiency of this method will directly affect the performance of the startup Activity, service, broadcast receiver, or content provider. Therefore, this method should be completed as quickly as possible.
Finally, if this callback interface is implemented, do not forget to call super. onCreate () the night before, otherwise the application will report an error.
We have implemented the subclass ------ Configuration of the Appplication class and the onCreate () method. Here we will make a small experiment to help you better understand this knowledge.
Now, add a wait of about 20 seconds to the onCreate () method of the source code to simulate () the modified code is as follows:
Public class ConfigApplication extends Application {private static final String TAG = "ConfigApplication"; private Configuration mConfiguration; @ Override public void onCreate () {super. onCreate (); this. mConfiguration = getResources (). getConfiguration (); // get the configuration Log. e (TAG, "onCreate: infomation: orientation =" + this. mConfiguration. orientation); SystemClock. sleep (20000); // sleep for 20 seconds} @ Override public void onConfigurationChanged (Configuration newConfig) {super. onConfigurationChanged (newConfig); // print the updated configuration Log. e (TAG, "onConfigurationChanged: infomation: orientation =" + newConfig. orientation );}}
At this time, the program will crash, of course, on the real device, it can wait, and some will not cause a crash, for example, tested on Xiaomi for 50 seconds, the program does not crash, but waits until the program is normal. This will lead to poor user experience. Therefore, in the future development process, we should fully consider these error-prone situations.
③ Use the onLowMemory () callback method to monitor low memory
The prototype of this method is:
Public void onLowMemory (){}
This method is called when the entire system runs in low memory.
A good application will implement this method to release any cache or other resources that are not needed. After the system returns this method, it will perform a garbage collection operation.
④ Use registerActivityLifecycleCallbacks () to register an interface that can monitor the Activity Lifecycle
The registerActivityLifecycleCallbacks () method is prototype:
Public void registerActivityLifecycleCallbacks (Application. ActivityLifecycleCallbacks callback ){}
In this method, callbacks indicates the Activity lifecycle interface.
Since Android and later, the Android SDK provides a complete set of interfaces for the Application to monitor the lifecycle of the Activity related to this Application (such as creation, startup, and suspension ), its name is ActivityLifecycleCallbacks. As long as you register the interface through the registerActivityLifecycleCallbacks () method in the Application, it will provide the relevant Activity lifecycle information in the Application through ActivityLifecycleCallbacks. The following table lists these interfaces and their usage.
Method prototype |
Parameter description |
Purpose |
Abstract void onActivityCreated (Activity activity, Bundle savedInstanceState) |
Activity: the created Activity instance. SavedInstanceState: information contained when the Activity is created (a Bundle instance) |
Called before an application creates an Activity to notify the interface implementer that the Activity will be created. |
Abstract void onActivityDestroyed (Activity activity) |
Activity: destroyed Activity instance |
Called before the application destroys the Activity to notify the real-time Activity of the interface to be destroyed. |
Abstract void onActivityPaused (Activity activity) |
Activity: Paused Activity instance |
Called before the application suspends the Activity to notify the interface implementer that the Activity will be paused. |
Abstract void onActivityResumed (Activity activity) |
Activity: the recovered Activity instance. |
Called before the application is resuming the Activity to notify the interface implementer that the Activity will be restored. |
Abstract void onActivitySaveInstanceState (Activity activity, Bundle outState) |
Activity: the Activity instance in the running status. OutState: Activity Status to be saved |
Indicates that the current Activity is saving its own status. These statuses are included in the outState. |
Abstract void onActivityStarted (Activity activity) |
Activity: the started Activity instance. |
Called before the application is starting the Activity to notify the interface implementer that the Activity will be started. |
Abstract void onActivityStopped (Activity activity) |
Activity: stopped Activity instance |
Called before the application is stopping the Activity to notify the interface implementer that the Activity is about to be stopped. |
Note: We can know the following information from the interface definition.
I. These interfaces are abstract. Therefore, when we implement the ActivityLifecycleCallbacks interface, we must implement these methods, even if they are just empty implementations.
II. The return values of these interfaces are void, which means they are only used for notifications and are not used for notifications.
In addition, when necessary, we need to call the unregisterActivityLifecycleCallbacks () method to cancel the previously registered interface to avoid unnecessary resource waste.
The following example shows how the system notifies the application through the onConfigurationChanged () callback interface when the configuration changes. The specific steps are as follows.
(I) Implement your own Application subclass (named ALCApplication ). We will register our own Activity lifecycle interface when the application is created (in the onCreate () method), and deregister this interface when the program ends (in the onTerMinate () method. After completing these tasks, you will get the following code:
public class ALCApplication extends Application { private final static String TAG="ALCApplication"; private ActivityLifecycleCallbacks mActivityLifecycleCallbacks=new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { Log.e(TAG,"onActivityCreated"); } @Override public void onActivityStarted(Activity activity) { Log.e(TAG,"onActivityStarted"); } @Override public void onActivityResumed(Activity activity) { Log.e(TAG,"onActivityResumed"); } @Override public void onActivityPaused(Activity activity) { Log.e(TAG,"onActivityPaused"); } @Override public void onActivityStopped(Activity activity) { Log.e(TAG,"onActivityStopped"); } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { Log.e(TAG,"onActivitySaveInstanceState"); } @Override public void onActivityDestroyed(Activity activity) { Log.e(TAG,"onActivityDestroyed"); } }; @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(this.mActivityLifecycleCallbacks); } @Override public void onTerminate() { super.onTerminate(); unregisterActivityLifecycleCallbacks(this.mActivityLifecycleCallbacks); }}
(Ii) Configure ALCApplication to AndroidManifest. xml. When the configuration is complete, the final result looks similar:
We use the interface to monitor the lifecycle of an Activity from startup to launch.
In this instance, we have logged out the interface in the onTerminate () method. However, it is worth noting that the onTerminate () method will only be called in the Virtual Machine Process and will never be called in the real Android device.
⑤ Use registerComponentCallbacks () to register an interface that can be used for the Activity lifecycle of a warship
This method is prototype:
Public void registerComponentCallbacks (ComponentCallbacks callback ){}
The callback parameter is an implementation of the ComponentCallbacks interface. When the lifecycle of an Activity changes, the application is notified through this interface. For all applications, it is the interface of a universal callback API set. ComponentCallbacks only includes two methods: public abstract void onConfigurationChanged (Configuration newConfig) and public abstract void onLowMemory (). The call conditions of the two methods are the same as those of the callback method with the same name in the Application.
The usage of the ComponentCallbacks () and registerComponentCallbacks () methods is the same as that of ActivityLifecycleCallbacks () and registerActivityLifecycleCallbacks.