definition
- A library that can be used to speed up the startup of the app;
- Provides a simple and efficient way to initialize components when App starts, and you can set the initialization order displayed by App Startup;
- Provides a ContentProvider to run the initialization of all dependencies, avoiding each third-party library using ContentProvider separately for initialization, thereby improving the startup speed of the application's program;
What problems have been solved
- If you introduce a lot of third-party libraries into your project, the code in Application may become like this (this is just part of the code of our actual project):
class MyApplication : Application() { override fun onCreate() { () (this); (this, new ()); initQbSdk(this); initRetrofit(); initDialogSetting(); initBugly(); initWeChat(); initUmeng(); initDoKit(); initNIM(); } ... }
- Some smarter library designers think that they can automatically call the initialization interface with ContentProvider to avoid initialization:
//1. Inherit ContentProvider and initialize it in onCreateclass MyProvider : ContentProvider() { override fun onCreate(): Boolean { context?.let { //Context can also be obtained in ContentProvider ().init(it) } return true } //Other methods cannot be used, just return null or return -1 ... } //2. ContentProvider is one of the four major components and needs to be registered in the file.<application ...> ... <provider android:name=".MyProvider" //The value of authorities has no fixed requirements, but it is necessary to ensure that the value is unique on the entire phone, so ${applicationId} is usually used as the prefix to prevent conflicts with other applications android:authorities="${applicationId}.myProvider" android:exported="false" /> </application> //3. When will the custom MyProvider be executed? The call process is as follows:() -> () -> () //This is automatically run and initialized during the cold startup stage. Let’s take a look at the Android 10 system source code.private void handleBindApplication(AppBindData data) { ... if (!) { if (!()) { // Create ContentProvider installContentProviders(app, ); } } ... try { // Call the OnCreate method that calls Application (app); } catch (Exception e) { ... } ... }
- The disadvantages of this solution: ContentProvider will add a lot of extra time. ContentProvider is one of the four major components of Android. This component is relatively heavyweight. In other words, my initialization operation may be a very lightweight operation, and after relying on ContentProvider, it becomes a heavyweight operation;
How to solve the problem
- Given the shortcomings of the first two, Google launches App Startup
- How does App Startup solve the problem? It can merge all ContentProviders for initialization into one, making the app start faster.
How to use
1. Introduce AppStartup dependencies
implementation ":startup-runtime:1.1.0-alpha01"
2. Implement the Initializer interface of the App Startup library
Define an Initializer interface for performing initialization and implement the App Startup library
class LjyToastInitializer : Initializer<Unit> { //Execute the code to be initialized in the create method override fun create(context: Context) { ().init(context) } //The dependencies method is used to configure whether the current LjyToastInitializer is still dependent on other Initializers. //If there is any configuration, just return emptyList() if not override fun dependencies(): List<Class<out Initializer<*>>> { return emptyList() } }
3. Configure MyInitializer in the library
<provider android:name="" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="" android:value="" /> </provider>
- When the app starts, the contentProvider built in the App Startup library will be automatically executed, and all registered Initializers will be searched in its ContentProvider, and then their create() method will be called one by one to perform initialization operations;
Delay initialization
- What should I do if I don't want to automatically initialize a library at startup, but instead want to manually initialize it at a specific time?
- First, by analyzing the source code, find the full path class name of the Initializer initialized by the library.
- Add the following configuration to the project:
<provider android:name="" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="" android:value="" tools:node="remove" /> </provider>
- Disable a single library and add tools:node="remove" to meta-data
- Disabling all libraries is to add tools:node="remove" to the provider tag
- Then manually initialize where needed
(this) .initializeComponent(LjyToastInitializer::)
- Delayed initialization is also very useful, which can reduce the start time of the app and improve the startup speed.
The above is the detailed explanation of the use of App Startup in the Android Jetpack series. For more information about Android Jetpack App Startup, please follow my other related articles!