Designing a Robust Android App Startup Framework with Annotation Processing and Task Scheduling
This article explains how to build a high‑performance Android startup framework by collecting initialization tasks with custom annotations, generating code via annotation processors, injecting tasks into the application, and scheduling them using a DAG‑based algorithm that supports async execution, multi‑process, and priority handling.
When an Android app integrates many SDKs, the Application class can become bloated and initialization order may involve complex dependencies, especially when asynchronous tasks are required. A well‑designed startup framework is therefore essential for reducing launch time.
The article first discusses why Google’s StartUp library, while convenient, lacks support for asynchronous tasks, modularization, multi‑process execution, and explicit priority control, making it unsuitable for large projects.
A qualified startup framework should provide the following capabilities:
Support for asynchronous tasks.
Component‑based modularization.
Explicit task dependencies.
Priority ordering.
Multi‑process execution.
To achieve these goals, the author defines a custom @InitTask annotation that describes each task’s name, background execution flag, priority, target processes, and dependent tasks. An interface IInitTask declares the execute(application: Application) method that each task must implement.
Using an annotation processor, the framework scans for classes annotated with @InitTask , creates TaskInfo objects, and generates a TaskRegister class for each module. The generated code registers tasks into a mutable list that later gets injected into the application’s initialization flow.
Code injection is performed with the AutoRegister library, which modifies the bytecode so that the collected tasks are added to the init() method of the final task register.
Task scheduling is implemented as a directed acyclic graph (DAG). The algorithm first checks for circular dependencies, builds child‑task relationships, and then executes tasks in the correct order: tasks without dependencies run first, and once a task finishes, its children are evaluated for execution.
Key scheduling functions include:
private fun checkCircularDependency(chain: List
, depends: Set
, taskMap: Map
) { ... } private fun execute(task: TaskInfo) { ... } private fun afterExecute(name: String, children: Set
) { ... }The framework also respects process constraints, skipping tasks whose target process does not match the current one, and distinguishes between background (asynchronous) and foreground (synchronous) execution using Kotlin coroutines.
Finally, the article provides usage instructions, Maven coordinates for the library, and links to the source repository on GitHub, encouraging readers to try the alpha version via JitPack.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.