Framework
HuolalaTech/hll-wp-therouter-android avatar
HuolalaTech/hll-wp-therouter-android

TheRouter: annotation-driven routing and cross-module injection for Android

A framework for assisting in the renovation of Android componentization(帮助 App 进行组件化改造的动态路由框架)

1,336 stars153 forksKotlinApache-2.0

At a glance

What is it?
TheRouter is Huolala's Android componentisation framework, where a page is annotated with a route path and navigated to by string rather than by class reference, so modules do not have to know about each other at compile time. Alongside navigation it provides cross-module dependency injection, automatic initialisation of a module, and dynamic loading of actions, and it is Apache 2.0 licensed.
Who is it for?
TheRouter suits an Android team that has outgrown a single module and needs business features to be developed and released independently, and that is prepared to adopt a routing-by-URL convention across the app.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 68 days ago.
What is it written in?
Mainly Kotlin, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What it is: the route becomes a string instead of a class reference

TheRouter is described as an Android componentisation solution and, in the repository description, a framework for assisting in the renovation of Android componentisation. The core idea is visible in the navigation API. A page declares its address with an annotation, @Route with a path, an action, a description and a list of params, and another module navigates to it by building a request from a string and calling navigation. The path in the example is an http:// style URI such as http://therouter.com/home, and the action is an action:// style scheme. The point of that is decoupling. A module that navigates to the home page does not reference the HomeActivity class, so the two modules can be compiled and shipped independently, which is the whole goal of splitting an Android application into independently releasable business features.

java
@Route(path = "http://therouter.com/home", action = "action://scheme.com",
        description = "second page", params = {"hello", "world"})
public class HomeActivity extends BaseActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TheRouter.build("Path")
            .withInt("intValue", 12345678)
            .withString("str_123_Value", "传中文字符串")
            .withBoolean("boolValue", true)
            .navigation();
    }
}

Four capabilities, each with its own wiki page

The core functions are listed as four things, and each links to a separate wiki page, which is the clearest sign of how much surface there is. Page Navigation is the Navigator, which is the route annotation mechanism. Cross-module dependency injection is the ServiceProvider, which is the piece that lets one module obtain an implementation from another without a compile-time dependency. Single module automatic initialisation is the FlowTaskExecutor, which is a lifecycle facility for a module to declare its own initialisation work and have it run in order. And the fourth is the ability to enable client apps to load a method dynamically, the ActionManager, which is the one to look at hardest because it is remote code loading by another name. The project is Apache 2.0 licensed, the primary language is Kotlin, and the homepage is therouter.cn.

The build: three artifacts, an annotation processor and a Gradle plugin

The Gradle configuration section is what a team has to absorb to use the framework, and it is three separate published artifacts. There is the plugin, cn.therouter:plugin, applied in the app module with apply plugin: 'therouter'. There is the apt artifact, cn.therouter:apt, added as a kapt dependency, which is the annotation processor that reads the @Route annotations at compile time. And there is the runtime library, cn.therouter:router, added as an implementation dependency. The root build.gradle adds the plugin to the classpath, and the versions of all three are pinned together, with the documented versions being 1.3.2 for each. The fact that an annotation processor is involved is the architectural point, because it means the route table is a build artefact, which is what makes the runtime independent of the modules it routes to.

java
// root build.gradle 
classpath 'cn.therouter:plugin:1.3.2'

// app module 
apply plugin: 'therouter'

// dependencies
kapt "cn.therouter:apt:1.3.2"
implementation "cn.therouter:router:1.3.2"

Almost no initialisation code, and where you do have to write some

The initialisation section is short because the point of the framework is that you write almost nothing. The library contains the automatic initialisation function internally, so there is no need for any initialisation code, although it is recommended that you set the Debug environment according to your business settings to view log information, which is done in the attachBaseContext override of the Application class through TheRouter.setDebug. The other place you write code is page parameter injection, which is called in the onCreate of an Activity or a Fragment, and the recommendation is to do it directly in the base Activity or Fragment so every page inherits it. The call is TheRouter.inject(this), and its job is to take the parameters that arrived with the navigation request and distribute them to the fields of the page, which is why the navigation builder offers typed setters for int, string, boolean, long, char, double and float.

java
@Override
protected void attachBaseContext(Context base) {
    TheRouter.setDebug(true or false);
    super.attachBaseContext(base);
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TheRouter.inject(this);
}

Proguard rules, and the keep rules the framework needs

There is a dedicated section for Proguard configuration, which is a tell that the framework is used in release builds and that shrinking is not optional. The first group is commented out and explains why, that you need to add rules for Fragment page routes, covering the android.app.Fragment class and the androidx.fragment.app.Fragment class and the older android.support.v4.app.Fragment class. The rules that are active keep the androidx.annotation.Keep annotation and any class marked with it, and then keep the members, fields, constructors and methods that carry it, and finally keep the fields annotated with com.therouter.router.Autowired. The last rule is the important one, since TheRouter injects into annotated fields and a shrinking build that removes them produces a page that navigates correctly and then has null fields.

The sample project, and debugging the plugin itself

The project structure section is the map of the repository and it is also the demonstration. The app/ module holds a sample, and business-a/, business-b/ and business-base/ are three modular business demos, so the sample is a miniature componentised application rather than a single screen. The apt/ directory is the annotation processor tool code, the plugin/ directory is the Gradle plugin, and the router/ directory is the library code, which matches the three published artifacts. The build and debug instructions are the part worth knowing. You declare which modules you want to debug in local.properties, for example setting apt=true, and then sync the Gradle change. Debugging the plugin itself is special, because the plugin runs at build time, so you rename the plugin folder to buildSrc, which is case sensitive, remove the classpath reference in the root build.gradle, and sync again.

Where the project stands, and the wider family

The README links the Android repository alongside a Harmony version and an iOS version, with a Chinese site at therouter.cn, so the framework is part of a family rather than a one-off. The default branch here is dev, and the recent releases are v1.3.1 on 2026-02-26, v1.3.2 on 2026-03-23 and v1.4.0-rc1 on 2026-03-25, so the 1.3 line is what the documentation describes while a 1.4 release candidate has been sitting unreleased for seven months. The last push to the repository was on 2026-08-20, the repository is not archived, and the licence is Apache 2.0. The project is credited to the Huolala mobile technology team, and the change log lives in the GitHub releases rather than in the repository.

Editorial conclusion

TheRouter suits an Android team that has outgrown a single module and needs business features to be developed and released independently, and that is prepared to adopt a routing-by-URL convention across the app. It is the wrong choice for a project with a handful of screens, because the annotation processor, the Gradle plugin and the build-time route table are a lot of machinery for a small navigation problem, and a poor fit if your organisation standardises on a different navigation approach such as Jetpack Compose navigation. Before adopting it, read the wiki pages for Navigator, ServiceProvider, FlowTaskExecutor and ActionManager, since each of the four features has its own page, and note that the annotation processor means a build step, so routes are only known after a compilation.

Frequently asked questions

What is TheRouter for Android?

It is an Android componentisation framework from Huolala that lets you navigate between pages by an annotated route path rather than a class reference, so independently developed business modules do not depend on each other at compile time. It also provides cross-module dependency injection, automatic single module initialisation and dynamic loading of actions, and it is Apache 2.0 licensed.

What are the three TheRouter artifacts and what does each do?

The Gradle plugin, cn.therouter:plugin, is applied to the app module. The annotation processor, cn.therouter:apt, is added as a kapt dependency and reads the @Route annotations at compile time to build the route table. The runtime library, cn.therouter:router, is added as an implementation dependency and performs the navigation and injection at runtime. All three are versioned together, at 1.3.2 in the documented configuration.

How do I navigate to a page with TheRouter?

The target page is annotated with @Route giving a path, an action and params, and the caller builds a request from a string with TheRouter.build, attaches typed parameters with methods such as withInt, withString, withBoolean, withLong, withChar, withDouble and withFloat, and calls navigation. Parameters are then distributed into the page by calling TheRouter.inject(this) in its onCreate.

What Proguard rules does TheRouter need?

You need to keep the androidx.annotation.Keep annotation and any class marked with it, keep its members, fields, constructors and methods, and keep fields annotated with com.therouter.router.Autowired. There are also commented-out rules for keeping Fragment classes, needed for Fragment page routes, and a release build that strips the annotated fields would produce pages that navigate correctly and then have null values.

How do I debug the TheRouter Gradle plugin?

Plugin debugging is special because the plugin runs at build time. You rename the plugin folder to buildSrc, which is case sensitive, remove the classpath reference in the root build.gradle, and sync the Gradle change. For the other modules you declare which ones to debug in local.properties, for example setting apt=true, and sync again.

Official sources

  1. HuolalaTech/hll-wp-therouter-android on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/huolalatech-hll-wp-therouter-android.svg)](https://hysenlabs.com/projects/huolalatech-hll-wp-therouter-android)

Was this useful?