Jetpack recently introduced a new library, AndroidX App Startup, to use to initialize components when launching applications in a simple and effective way. This article we will learn together about this library.
1. Why use the AndroidX App Startup
Normally, in an Android application, it is possible to use some libraries that run the initialization logic when starting the application. For example, WorkManager and Lifecycle are initialized when the application is run. Users always want to initialize these components as quickly as possible, but sometimes having multiple ContentProvider launched can slow down the initialization time of the application, making the user experience will not be good. . So App Startup was created to overcome this situation by instead of declaring separate ContentProvider for individual components at initialization, App Startup allows you to define a single ContentProvider for all of the components. That will greatly improve the application startup time.
2. How to use it
To use App Startup in the application, add the following setting to the gradle file:
1 2 3 4 | dependencies <span class="token punctuation">{</span> implementation <span class="token string">"androidx.startup:startup-runtime:1.0.0-alpha01"</span> <span class="token punctuation">}</span> |
2.1. Initialization
Create class implement Initializer
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token comment">// Initializes WorkManager.</span> <span class="token keyword">class</span> <span class="token class-name">WorkManagerInitializer</span> <span class="token operator">:</span> Initializer <span class="token generics function"><span class="token punctuation"><</span> WorkManager <span class="token punctuation">></span></span> <span class="token punctuation">{</span> override fun <span class="token function">create</span> <span class="token punctuation">(</span> context <span class="token operator">:</span> Context <span class="token punctuation">)</span> <span class="token operator">:</span> WorkManager <span class="token punctuation">{</span> val configuration <span class="token operator">=</span> Configuration <span class="token punctuation">.</span> <span class="token function">Builder</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">build</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> WorkManager <span class="token punctuation">.</span> <span class="token function">initialize</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> configuration <span class="token punctuation">)</span> <span class="token keyword">return</span> WorkManager <span class="token punctuation">.</span> <span class="token function">getInstance</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token punctuation">}</span> override fun <span class="token function">dependencies</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> List <span class="token operator"><</span> Class <span class="token operator"><</span> out Initializer <span class="token operator"><</span> <span class="token operator">*</span> <span class="token operator">>>></span> <span class="token punctuation">{</span> <span class="token comment">// No dependencies on other libraries.</span> <span class="token keyword">return</span> <span class="token function">emptyList</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
For example, the application is dependent on WorkManager and needs to be initialized to run the application. Declare a class WorkManagerInitializer implement Initializer
- The create () method, containing all the work needed to initialize the component and return 1 instance T
- method dependencies () return 1 list of other Initializers on which the initializer currently depends. Use this method to control the initialization order of the components when the application launches
The dependencies () return 1 list is empty because WorkManager does not depend on any other library.
For example, there is another library called ExampleLogger, it depends on WorkManager. That is, you need to initialize WorkManager first, then initialize ExampleLogger.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token comment">// Initializes ExampleLogger.</span> <span class="token keyword">class</span> <span class="token class-name">ExampleLoggerInitializer</span> <span class="token operator">:</span> Initializer <span class="token generics function"><span class="token punctuation"><</span> ExampleLogger <span class="token punctuation">></span></span> <span class="token punctuation">{</span> override fun <span class="token function">create</span> <span class="token punctuation">(</span> context <span class="token operator">:</span> Context <span class="token punctuation">)</span> <span class="token operator">:</span> ExampleLogger <span class="token punctuation">{</span> <span class="token comment">// WorkManager.getInstance() is non-null only after</span> <span class="token comment">// WorkManager is initialized.</span> <span class="token keyword">return</span> <span class="token function">ExampleLogger</span> <span class="token punctuation">(</span> WorkManager <span class="token punctuation">.</span> <span class="token function">getInstance</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> override fun <span class="token function">dependencies</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> List <span class="token operator"><</span> Class <span class="token operator"><</span> out Initializer <span class="token operator"><</span> <span class="token operator">*</span> <span class="token operator">>>></span> <span class="token punctuation">{</span> <span class="token comment">// Defines a dependency on WorkManagerInitializer so it can be</span> <span class="token comment">// initialized after WorkManager is initialized.</span> <span class="token keyword">return</span> <span class="token function">listOf</span> <span class="token punctuation">(</span> WorkManagerInitializer <span class="token operator">:</span> <span class="token operator">:</span> <span class="token keyword">class</span> <span class="token punctuation">.</span> java <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
2.2. Set up manifest entries
App Startup has a content provider that InitializationProvider uses to declare in AndroidManifest the initializer component. You need to declare the initializer in the meta-data tag pair in the InitializationProvider entry. App Startup will then call the method dependencies () and get the components in it to initialize.
1 2 3 4 5 6 7 8 9 10 | <span class="token operator"><</span> provider android <span class="token operator">:</span> name <span class="token operator">=</span> <span class="token string">"androidx.startup.InitializationProvider"</span> android <span class="token operator">:</span> authorities <span class="token operator">=</span> <span class="token string">"${applicationId}.androidx-startup"</span> android <span class="token operator">:</span> exported <span class="token operator">=</span> <span class="token string">"false"</span> tools <span class="token operator">:</span> node <span class="token operator">=</span> <span class="token string">"merge"</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">!</span> <span class="token operator">--</span> This entry makes ExampleLoggerInitializer discoverable <span class="token punctuation">.</span> <span class="token operator">--</span> <span class="token operator">></span> <span class="token operator"><</span> meta <span class="token operator">-</span> data android <span class="token operator">:</span> name <span class="token operator">=</span> <span class="token string">"com.example.ExampleLoggerInitializer"</span> android <span class="token operator">:</span> value <span class="token operator">=</span> <span class="token string">"androidx.startup"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> provider <span class="token operator">></span> |
You do not need to add meta-data tag pairs for WorkManagerInitializer because WorkManagerInitializer is a dependency of ExampleLoggerInitializer. That is when initializing ExampleLoggerInitializer, WorkManagerInitializer has also been initialized already.
The tools: node = “merge” attribute ensures that the manifest merger resolves conflicts correctly.
Run lint check
The App Startup Library includes a set of lint rules that you can use to check that you have correctly identified your component initialization tools. You can perform these lint checks by running ./gradlew: app: lintDebug from the command line.
2.3. Self-run initialization component
Normally when you use App Startup, the InitializationProvider object uses an entity named AppInitializer to automatically run initialization components when starting the application. However, you can also use AppInitializer directly to manually initialize components that your application does not need at startup. This is called lazy initialization and it can help minimize startup.
First, you must turn off automatic initialization for any component you want to manually initialize.
2.3.1. Disable automatic initialization with 1 independent component
1 2 3 4 5 6 7 8 9 | <span class="token operator"><</span> provider android <span class="token operator">:</span> name <span class="token operator">=</span> <span class="token string">"androidx.startup.InitializationProvider"</span> android <span class="token operator">:</span> authorities <span class="token operator">=</span> <span class="token string">"${applicationId}.androidx-startup"</span> android <span class="token operator">:</span> exported <span class="token operator">=</span> <span class="token string">"false"</span> tools <span class="token operator">:</span> node <span class="token operator">=</span> <span class="token string">"merge"</span> <span class="token operator">></span> <span class="token operator"><</span> meta <span class="token operator">-</span> data android <span class="token operator">:</span> name <span class="token operator">=</span> <span class="token string">"com.example.ExampleLoggerInitializer"</span> tools <span class="token operator">:</span> node <span class="token operator">=</span> <span class="token string">"remove"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> provider <span class="token operator">></span> |
Use tools: node = “remove”
Note: when auto-initialization is disabled, auto-initialization for dependent components is also used
2.3.2. Turn off auto-initialization for all components
1 2 3 4 5 | <span class="token operator"><</span> provider android <span class="token operator">:</span> name <span class="token operator">=</span> <span class="token string">"androidx.startup.InitializationProvider"</span> android <span class="token operator">:</span> authorities <span class="token operator">=</span> <span class="token string">"${applicationId}.androidx-startup"</span> tools <span class="token operator">:</span> node <span class="token operator">=</span> <span class="token string">"remove"</span> <span class="token operator">/</span> <span class="token operator">></span> |
If auto-initialization is disabled for a component, you can use AppInitializer to initialize the component itself and its dependencies.
1 2 3 | AppInitializer <span class="token punctuation">.</span> <span class="token function">getInstance</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">initializeComponent</span> <span class="token punctuation">(</span> ExampleLoggerInitializer <span class="token operator">:</span> <span class="token operator">:</span> <span class="token keyword">class</span> <span class="token punctuation">.</span> java <span class="token punctuation">)</span> |
Refer