Khởi động ứng dụng Một phần của Android Jetpack.

Thư viện Khởi động ứng dụng cung cấp một cách đơn giản và hiệu quả để khởi chạy các thành phần khi khởi động ứng dụng. Cả nhà phát triển thư viện lẫn nhà phát triển ứng dụng đều có thể dùng tính năng Khởi động ứng dụng để tinh giản trình tự khởi động và đặt thứ tự khởi động một cách rõ ràng.

Thay vì xác định các nhà cung cấp nội dung riêng biệt cho từng thành phần bạn cần khởi chạy, tính năng Khởi động ứng dụng cho phép bạn xác định các trình khởi chạy thành phần dùng chung một nhà cung cấp nội dung. Giải pháp này có thể giúp cải thiện đáng kể thời gian khởi động ứng dụng.

Thiết lập

Để dùng tính năng Khởi động Jetpack trong thư viện hoặc ứng dụng, hãy thêm đoạn mã sau vào tệp Gradle:

Groovy

dependencies {
    implementation "androidx.startup:startup-runtime:1.1.1"
}

Kotlin

dependencies {
    implementation("androidx.startup:startup-runtime:1.1.1")
}

Khởi chạy các thành phần khi khởi động ứng dụng

Các ứng dụng và thư viện thường dựa vào việc khởi chạy các thành phần ngay lập tức khi ứng dụng khởi động. Bạn có thể đáp ứng nhu cầu này bằng cách sử dụng nhà cung cấp nội dung để khởi động từng phần phụ thuộc, nhưng trình cung cấp nội dung rất tốn kém khi tạo bản sao và có thể làm chậm trình tự khởi động một cách không cần thiết. Ngoài ra, Android khởi chạy các trình cung cấp nội dung theo thứ tự chưa xác định. Khởi động ứng dụng cung cấp một cách hiệu quả hơn để khởi chạy các thành phần khi khởi động ứng dụng và xác định rõ các phần phụ thuộc của các thành phần đó.

Để sử dụng tính năng Khởi động ứng dụng nhằm tự động khởi chạy các thành phần khi khởi động, bạn phải xác định trình khởi chạy thành phần cho mỗi thành phần mà ứng dụng cần khởi chạy.

Triển khai trình khởi tạo thành phần

Bạn xác định từng trình khởi chạy thành phần bằng cách tạo một lớp triển khai giao diện Initializer<T>. Giao diện này xác định 2 phương thức quan trọng:

  • Phương thức create() chứa tất cả các thao tác cần thiết để khởi động thành phần và trả về một thực thể của T.
  • Phương thức dependencies() trả về danh sách các đối tượng Initializer<T> khác mà trình khởi tạo phụ thuộc vào. Bạn có thể sử dụng phương thức này để kiểm soát thứ tự ứng dụng chạy trình khởi chạy khi khởi động.

Ví dụ: giả sử ứng dụng của bạn phụ thuộc vào WorkManager và cần khởi động ứng dụng đó khi khởi động. Xác định một lớp WorkManagerInitializer triển khai Initializer<WorkManager>:

Kotlin

// Initializes WorkManager.
class WorkManagerInitializer : Initializer<WorkManager> {
    override fun create(context: Context): WorkManager {
        val configuration = Configuration.Builder().build()
        WorkManager.initialize(context, configuration)
        return WorkManager.getInstance(context)
    }
    override fun dependencies(): List<Class<out Initializer<*>>> {
        // No dependencies on other libraries.
        return emptyList()
    }
}

Java

// Initializes WorkManager.
class WorkManagerInitializer implements Initializer<WorkManager> {

    @Override
    public WorkManager create(Context context) {
        Configuration configuration = Configuration.Builder().build();
        WorkManager.initialize(context, configuration);
        return WorkManager.getInstance(context);
    }

    @Override
    public List<Class<Initializer<?>>> dependencies() {
        // No dependencies on other libraries.
        return emptyList();
    }

}

Phương thức dependencies() trả về một danh sách trống vì WorkManager không phụ thuộc vào bất kỳ thư viện nào khác.

Giả sử ứng dụng của bạn cũng phụ thuộc vào thư viện có tên là ExampleLogger và thư viện này phụ thuộc vào WorkManager. Phần phụ thuộc này có nghĩa là bạn cần đảm bảo rằng tính năng Khởi động ứng dụng sẽ khởi chạy WorkManager trước tiên. Xác định một lớp ExampleLoggerInitializer triển khai Initializer<ExampleLogger>:

Kotlin

// Initializes ExampleLogger.
class ExampleLoggerInitializer : Initializer<ExampleLogger> {
    override fun create(context: Context): ExampleLogger {
        // WorkManager.getInstance() is non-null only after
        // WorkManager is initialized.
        return ExampleLogger(WorkManager.getInstance(context))
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        // Defines a dependency on WorkManagerInitializer so it can be
        // initialized after WorkManager is initialized.
        return listOf(WorkManagerInitializer::class.java)
    }
}

Java

// Initializes ExampleLogger.
class ExampleLoggerInitializer implements Initializer<ExampleLogger> {

    @Override
    public ExampleLogger create(Context context) {
        // WorkManager.getInstance() is non-null only after
        // WorkManager is initialized.
        return ExampleLogger(WorkManager.getInstance(context));
    }

    @Override
    public List<Class<Initializer<?>>> dependencies() {
        // Defines a dependency on WorkManagerInitializer so it can be
        // initialized after WorkManager is initialized.
        return Arrays.asList(WorkManagerInitializer.class);
    }
}

Vì bạn đưa WorkManagerInitializer vào phương thức dependencies(), nên tính năng Khởi động ứng dụng sẽ khởi chạy WorkManager trước ExampleLogger.

Thiết lập các mục trong tệp kê khai

Khởi động ứng dụng bao gồm một trình cung cấp nội dung đặc biệt có tên là InitializationProvider. Trình cung cấp này sử dụng để khám phá và gọi trình khởi chạy thành phần của bạn. Tính năng Khởi động ứng dụng khám phá trình khởi chạy thành phần bằng cách kiểm tra mục nhập <meta-data> trước mục nhập tệp kê khai InitializationProvider. Sau đó, tính năng Khởi động ứng dụng sẽ gọi các phương thức dependencies() cho mọi trình khởi chạy mà tính năng này đã phát hiện được.

Tức là để Khởi động ứng dụng có thể phát hiện trình khởi tạo thành phần, bạn phải đáp ứng một trong các điều kiện sau:

  • Trình khởi tạo thành phần có mục nhập <meta-data> tương ứng trong mục kê khai InitializationProvider.
  • Trình khởi tạo thành phần được liệt kê trong phương thức dependencies() từ một trình khởi tạo có thể phát hiện được.

Hãy xem xét lại ví dụ với WorkManagerInitializerExampleLoggerInitializer. Để đảm bảo quy trình Khởi động ứng dụng có thể khám phá các trình khởi chạy này, hãy thêm những nội dung sau vào tệp kê khai:

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

Bạn không cần thêm mục nhập <meta-data> cho WorkManagerInitializer, vì WorkManagerInitializer là phần phụ thuộc của ExampleLoggerInitializer. Điều này có nghĩa là nếu ExampleLoggerInitializer có thể phát hiện được, thì WorkManagerInitializer cũng vậy.

Thuộc tính tools:node="merge" đảm bảo rằng công cụ hợp nhất tệp kê khai giải quyết đúng cách mọi mục nhập xung đột.

Chạy quá trình kiểm tra tìm lỗi mã nguồn

Thư viện Khởi động ứng dụng bao gồm một bộ quy tắc tìm lỗi mã nguồn mà bạn có thể dùng để kiểm tra xem mình đã xác định đúng trình khởi chạy thành phần hay chưa. Bạn có thể thực hiện các bước kiểm tra tìm lỗi mã nguồn này bằng cách chạy ./gradlew :app:lintDebug từ dòng lệnh.

Khởi chạy các thành phần theo cách thủ công

Thông thường, khi bạn sử dụng tính năng Khởi động ứng dụng, đối tượng InitializationProvider sẽ dùng một thực thể có tên là AppInitializer để tự động phát hiện và chạy trình khởi chạy thành phần khi khởi động ứng dụng. Tuy nhiên, bạn cũng có thể sử dụng trực tiếp AppInitializer để khởi động các thành phần mà ứng dụng không cần đến khi khởi động theo cách thủ công. Quá trình này được gọi là khởi chạy từng phần và có thể giúp giảm thiểu chi phí khởi động.

Trước tiên, bạn phải tắt tính năng khởi chạy tự động cho mọi thành phần mà bạn muốn khởi chạy theo cách thủ công.

Tắt tính năng khởi chạy tự động cho một thành phần riêng lẻ

Để tắt tính năng khởi chạy tự động cho một thành phần, hãy xoá mục nhập <meta-data> cho trình khởi chạy của thành phần đó khỏi tệp kê khai.

Ví dụ: việc thêm nội dung sau đây vào tệp kê khai sẽ tắt tính năng tự động khởi chạy cho ExampleLogger:

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

Bạn sử dụng tools:node="remove" trong mục nhập thay vì chỉ xoá mục nhập để đảm bảo rằng công cụ sáp nhập cũng sẽ xoá mục nhập đó khỏi mọi tệp kê khai hợp nhất khác.

Tắt tính năng khởi chạy tự động cho tất cả thành phần

Để tắt toàn bộ hoạt động khởi chạy tự động, hãy xoá toàn bộ mục nhập cho InitializationProvider khỏi tệp kê khai:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove" />

Gọi trình khởi tạo thành phần theo cách thủ công

Nếu tắt tính năng khởi chạy tự động cho một thành phần, bạn có thể sử dụng AppInitializer để khởi chạy thành phần đó và các phần phụ thuộc của thành phần đó theo cách thủ công.

Ví dụ: mã sau đây gọi AppInitializer và khởi chạy ExampleLogger theo cách thủ công:

Kotlin

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

Java

AppInitializer.getInstance(context)
    .initializeComponent(ExampleLoggerInitializer.class);

Do đó, tính năng Khởi động ứng dụng cũng khởi chạy WorkManagerWorkManager là phần phụ thuộc của ExampleLogger.

Gửi ý kiến phản hồi

Hãy chia sẻ phản hồi và ý kiến của bạn với chúng tôi thông qua các tài nguyên sau:

Công cụ theo dõi lỗi
Báo cáo sự cố để chúng tôi có thể sửa lỗi.