Preface

When learning an SDK, I came across relevant knowledge of Application class. In fact, I also learned some knowledge of Application class before, but I didn’t use it frequently in daily development, so I almost forgot it. Now to summarize the use of Application again

Good English foundation can refer to the official documents

The official documentation

The following is a brief introduction of the Application class on the official website

Base class for maintaining global application state. You can provide your own implementation by creating a subclass and specifying the fully-qualified name of this subclass as the "android:name" attribute in your AndroidManifest.xml’s <application> tag. The Application class, or your subclass of the Application class, is instantiated before any other class when the process for your application/package is created.

Application is a base class used to maintain global Application state. You can implement custom functionality by creating your own subclasses and marking them with the name attribute in the manifest.xml file. The Application class will be instantiated before any classes

Inheritance relationships

  • ApplicationClass inherits fromContextWarpperclass

Here’s the schematic

The characteristics of

  • Singleton mode: Each App has only one instance of Application (except multi-process apps), which can be customized by subclassing Application. If there is no customization, the App will automatically create a default instance when opened.

  • Life cycle: The Application object is instantiated when the APP is started. The Application instance has the longest life cycle and has the same life cycle as the APP

  • Access: if there is no custom Application, also can obtain the Application object, use the Activity. The getApplication () or Context. GetApplicationContext () method can access to the object.

override fun onCreate(savedInstanceState: Bundle?). {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Both methods can get instance objects
    val application = application
    val otherApplication = applicationContext
}
Copy the code
  • Global instance: Application objects can be retrieved from different components (e.g. Activity,Service), and are always the same object

Methods to introduce

onCreate()

  • Call time:

    This method is called when the application is created when the application is open.

Tip: This is not the Activity’s onCreate() implementation, which is empty by default.

  • Usage:

    Can be used to initialize data some global variables, objects, can also be used to do some environment configuration.

  • Presentation:

class MyApplication: Application() {
    var whatever = "Whatever"
    
    override fun onCreate(a) {
        super.onCreate()
        whatever = "Hello"
        //Do something...}}Copy the code

Registered ComponentCallback2

  • Brief description:

    The diagram above, actually also shows the Application class is realized ComponentCallback2 interface, this interface has three can override a method, by registerComponentCallbacks () method to register, can also use unregi SterComponentCallbacks () to log out.

  • Use:

override fun onCreate(a) {
        super.onCreate()
    
        registerComponentCallbacks(object : ComponentCallbacks2 {
            override fun onLowMemory(a){}override fun onConfigurationChanged(newConfig: Configuration?).{}override fun onTrimMemory(level: Int){}})}Copy the code

onLowMemory()

This is the method in the ComponentCallback2 interface above, used before Android4.0 memory detection, developers can make some optimization in this callback method, to prevent the system to kill the process. It’s not very common to use this approach at the moment, unless developers want to go deeper into backwards compatibility. You can now use onTrimMemory() instead

  • Call time: Listen for the moment when system memory is low
registerComponentCallbacks(object : ComponentCallbacks2 {
            override fun onLowMemory(a) {
				//Do something...}})Copy the code

onTrimMemoey()

This method is currently used to replace the onLowMemory() method above. Method passes a level Int, which is a current level of out-of-memory that the system notifies the App. The higher the level, the more serious it is. Different rating systems do different things to the App.

Out of memory level meaning
TRIM_MEMORY_RUNNING_MODERATE Level 5: Applications can run in the foreground, but the system has started to kill background processes
TRIM_MEMORY_RUNNING_LOW Level 10: The application can run normally in the foreground, but the system notifies you to release resources, otherwise the speed will be affected
TRIM_MEMORY_RUNNING_CRITICAL Level 15: Foreground running, but most of the background is killed. Memory must be freed or the application will be killed
TRIM_MEMORY_UI_HIDDEN Level 20: The system reclaims the UI resources of the application and transfers them to the background
TRIM_MEMORY_BACKGROUND Level 40: The application is in the nearest position in the LRU cache list and needs to release easily recoverable resources immediately
TRIM_MEMORY_MODERATE Level 60: The application is in the middle of the LRU cache list and is in danger of being killed
TRIM_MEMORY_COMPLETE Level 80: Very dangerous level. The application is at the very edge of the cache list and is about to be killed
  • System process killing rules:

    The system kills processes from the lowest to the highest in the LRU Cache list, and preferentially kills applications that occupy a large memory. If an application occupies a small memory, the probability of being killed is reduced.

  • Usage:

override fun onTrimMemory(level: Int) {
    if (level inTRIM_MEMORY_RUNNING_MODERATE.. (TRIM_MEMORY_RUNNING_LOW -1)) {//Do something...
    }else if (level >= TRIM_MEMORY_RUNNING_LOW){
		//Do something...}}Copy the code

onConfigurationChanged()

  • Function:

    Listen for APP configuration changes (such as screen rotation)

  • Call time:

    This method is called back when configuration information changes

  • Configuration information:

    Configuration information is also Manifest. Activity in the XML files in the android: configChanges attribute’s value, fill in the property with the android: configChanges = “keyboardHidden | orientation | screen The Size” allows the screen to be rotated without rebooting and instead executes the onConfigurationChanged() method

  • Usage:

registerComponentCallbacks(object : ComponentCallbacks2 {
    override fun onConfigurationChanged(newConfig: Configuration?). {
		//Do something}}Copy the code

ActivityLifecycleCallbacks()

This is an interface, can pass registerActivityLifecycleCallbacks () and unregisterActivityLifecycleCallbacks () to register/cancellation of listening to all the Activity life cycle, when the Activity When the life cycle of the interface changes, methods in the interface are called.

  • Method of use
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityPaused(activity: Activity?).{}override fun onActivityResumed(activity: Activity?).{}override fun onActivityStarted(activity: Activity?).{}override fun onActivityDestroyed(activity: Activity?).{}override fun onActivitySaveInstanceState(activity: Activity? , outState:Bundle?).{}override fun onActivityStopped(activity: Activity?).{}override fun onActivityCreated(activity: Activity? , savedInstanceState:Bundle?).{}})Copy the code

This is basically just listening for different life cycles, so I’m not going to write the operation code in there. If you’re interested, you can add your own Log tests.

onTerminate()

At the end of the program will call, just for the simulator test, real machine will not call, nothing to say.

registerOnProvideAssistDataListener()&unregisterOnProvideAssistDataListener()

This two methods need to be able to be registered name is prepared to voice assistant data listener, need the incoming OnProvideAssistDataListener interface object, interface in only one onProvideAssistData (Activity Activity, Bundle When the user launches the voice assistant, it builds an intent.action_assist. It also attaches the user’s location and context when the user requests help.

Read online is overseas phone calls are voice assistant will call this method, I guess it should not be foreign mobile phone, but Google voice assistant, I use OxygenOS system test and found that indeed on the exhale Google assistant called when the method, the Bundle is not empty, but I did not find information in it, and should be me in the right way I haven’t figured out how to use it yet. If you know the cattle trouble to guide

  • My test:
registerOnProvideAssistDataListener { activity, data ->
         if (data= =null) {
             Log.d("Log"."Bundle is empty")}else {
             var string = "Bundle{"
             for (item in data.keySet()) {
                 string += " $item= >${data.get(item)};"
             }
             string += "}Bundle"
             Log.d("Log",string)
             Log.d("Log"."data is:$ACTION_ASSIST + $EXTRA_ASSIST_PACKAGE + $EXTRA_ASSIST_CONTEXT")
             startActivity(object :Intent(ACTION_ASSIST){})
         }
}
Copy the code
  • Test results:
Bundle{}Bundle data is:android.intent.action.ASSIST + android.intent.extra.ASSIST_PACKAGE + android.intent.extra.ASSIST_CONTEXTCopy the code

The custom Application

Now it is time to customize the Application class. There are not many steps to customize the Application class.

  • Create subclasses that inherit from the Application class

    There’s nothing to talk about here, can we just look at the code

class MyApplication : Application() {

    override fun onCreate(a) {
        super.onCreate()
		//DO something...}}Copy the code
  • Enter Manifest to configure custom classes
<application
         android:name=".MyApplication"            
</application>
Copy the code
  • Get an instance of the Application class

    The method of obtaining an instance has been described above, so I won’t repeat it here.

role

You generally do not need to customize an Application class, but you can customize an Application class if you need to implement the following functionality

  • Initialize partial resources (global objects, global shared variables, methods, etc.)
  • Optimize memory footprint
  • Listen for APP configuration information and the life cycle of all activities