The use and deficiency of Jetpack's App Startup, and the improved version of Android-Startup

On October 28, 2020, JetPack | App Startup 1.0.0  finally ushered in the official release.

The application startup library provides a simple and efficient way to initialize components when the application starts. Both library developers and application developers can use application startup to simplify the startup sequence and explicitly set the initialization order.

Instead of defining a separate content provider for each component that needs to be initialized, App Startup allows you to define component initializers that share a single content provider. This can significantly reduce application startup time.

Table of contents


Pre-knowledge

The content of this article will involve the following pre-requisite/related knowledge, and I have prepared it for you, please enjoy~


1. Why use App Startup?

In this section, let's discuss why App Startup is used, that is, what problems App Startup solves.

The non-invasive method of obtaining Context based on the ContentProvider startup mechanism : "Android | Use ContentProvider to obtain Context without intrusion" . Here I briefly recap:

  • 1. In the second-party library or third-party library, it is often necessary to obtain the Context for initialization;
  • 2. Because the ContentProvider will be initialized when the application starts, many libraries use the ContentProvider startup mechanism Application#onCreate()to initialize in it, such as LeakCanary 2.4 :

AppWatcherInstaller.java

internal sealed class AppWatcherInstaller : ContentProvider() {

    internal class MainProcess : AppWatcherInstaller()

    internal class LeakCanaryProcess : AppWatcherInstaller()

    override fun onCreate(): Boolean {
        val application = context!!.applicationContext as Application
        AppWatcher.manualInstall(application)
        return true
    }

    // 其他方法直接 return 
}
  • 3. The risk of this approach is that there are too many ContentProviders, and starting too many ContentProviders will increase the startup time of the application.

  • 4. AppStartup's approach is to merge all ContentProviders used for initialization, reduce the creation of ContentProviders, and provide global management .


2. Steps to use

In this section, let's summarize the steps of using App Startup. The dependencies are as follows:

build.gradle

implementation "androidx.startup:startup-runtime:1.0.0"

2.1 Implement the Initializer interface for the component

InitializerThe interface is the component interface encapsulated by Startup, which is used to specify the initialization logic and initialization sequence (that is, the dependency relationship) of the component.

Initializer.java

public interface Initializer<T> {

    1、初始化操作,返回的初始化结果将被缓存
    @NonNull
    T create(@NonNull Context context);

    2、依赖关系,返回值是一个依赖组件的列表
    @NonNull
    List<Class<? extends Initializer<?>>> dependencies();
}
  • 1. create(...)Initialization operation: the returned initialization result will be cached, and contextthe parameter is Application;
  • 2. dependencies()Dependency: The return value is a list of dependent components. If there is no need to depend on other components, return an empty list. When App Startup initializes the current component, it will ensure that the dependent components have been initialized.

2.2 Automatic initialization

As mentioned earlier, App Startup merges all ContentProviders used for initialization. The merged ContentProvider is what InitializationProviderwe need to AndroidManifestdeclare in, for example:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <meta-data
        android:name="com.example.ExampleLoggerInitializer"
        android:value="androidx.startup" />
</provider>

The main points are as follows:

  • 1. The component name must be androidx.startup.InitializationProvider;
  • 2. A statement is required android:exported="false"to restrict other applications from accessing this component;
  • 3. It is required to be android:authoritiesunique in the entire mobile phone, usually using ${applicationId} as a prefix;
  • 4. It needs to be declared tools:node="merge"to ensure that manifest merger toolthe conflicting nodes can be resolved correctly;
  • 5. Meta-data nameis the fully qualified name of the component's Initializer implementation class, valuewhich is androidx.startup.

Tip: Why would you want to androidx.startupset it to value, instead of name? Because the key-value pair nameis unique, valuebut duplicates are allowed.

About AndroidManifesthow App Startup automatically performs initialization after declaring components in , I said in Section 3 .

2.3 Manual initialization

When a component needs to be lazy loaded (a time-consuming task), manual initialization can be performed. Initializers that require manual initialization do not need AndroidManifestto be declared in , nor should they be relied upon by other components. Manual initialization can be done by calling:

AppInitializer.getInstance(context)
.initializeComponent(ExampleLoggerInitializer::class.java)

It should be noted that the initialization result will be cached in App Startup, and repeated calls initializeComponent()will not lead to repeated initialization. About the source code analysis of the manual initialization part of App Startup, I said in Section 3 .

2.4 Cancel automatic initialization

If some libraries have been configured with automatic initialization using the method in section 2.2 , and we want to perform lazy loading, we need to use the manifest merger toolmerge rules to remove the corresponding Initializer of this library. details as follows:

<provider
    android:name="andro

Guess you like

Origin blog.csdn.net/MYBOYER/article/details/124035680