android ARouter 讲解

0 阅读4分钟

ARouter 是阿里开源的 Android 页面路由框架,主要解决大型项目中 Activity、Fragment、Service 等组件之间解耦的问题。

如果你做的是中大型 Android 项目(尤其是组件化、模块化项目),ARouter 几乎是最常见的路由框架之一。


一、为什么需要 ARouter?

先看没有 ARouter 的情况。

假设有三个模块:

app
│
├── login
├── user
└── order

订单模块需要跳转到登录页。

传统写法:

Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);

问题来了:

order
   │
   ▼
login

order 模块必须依赖 login 模块。

如果越来越多模块互相依赖:

A -> B
A -> C
B -> C
C -> D

依赖关系越来越乱。

组件化项目希望:

A

B      Router

C

D

大家都依赖 Router,而不是彼此依赖。

这就是 ARouter 存在的意义。


二、ARouter 的核心思想

ARouter 就像 Android 的 Uri。

例如:

https://www.baidu.com/user/login

对应页面:

LoginActivity

ARouter 也是类似:

/login/LoginActivity

跳转:

ARouter.getInstance()
        .build("/login/LoginActivity")
        .navigation();

你不用知道:

LoginActivity.class

只需要知道:

"/login/LoginActivity"

即可。


三、ARouter 工作流程

例如:

ARouter.getInstance()
        .build("/user/detail")
        .withString("id","100")
        .navigation();

流程:

build()
      │
      ▼
Postcard
      │
      ▼
Warehouse
      │
      ▼
找到 UserDetailActivity
      │
      ▼
创建 Intent
      │
      ▼
startActivity()

整个流程如下:

String Path
      │
      ▼
RouteMeta
      │
      ▼
Activity.class
      │
      ▼
Intent
      │
      ▼
Activity

四、ARouter 的组成

1、@Route

用于注册页面。

例如:

@Route(path = "/login/main")
public class LoginActivity extends AppCompatActivity {

}

path 就是唯一标识。

推荐格式:

/模块名/页面名

例如:

/login/main

/user/detail

/order/list

/home/main

不要写:

/abc

/test

/main

后期维护非常困难。


2、build()

构建一个路由。

ARouter.getInstance()
        .build("/login/main");

实际上返回:

Postcard

类似:

Postcard
    path
    group
    extras

3、navigation()

真正开始跳转。

例如:

ARouter.getInstance()
        .build("/login/main")
        .navigation();

最终内部还是:

startActivity(intent);

五、传递参数

ARouter 与 Intent 的使用方式非常相似。

例如:

ARouter.getInstance()
        .build("/user/detail")
        .withString("name","Tom")
        .withInt("age",18)
        .navigation();

接收:

@Route(path = "/user/detail")
public class UserActivity extends AppCompatActivity {

    @Autowired
    String name;

    @Autowired
    int age;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ARouter.getInstance().inject(this);

        Log.d("TAG", name);
        Log.d("TAG", age + "");
    }
}

注意:

ARouter.getInstance().inject(this);

必须调用。

否则:

@Autowired

不会注入。

你之前问过 ARouter.getInstance().inject(this) 什么时候调用,答案就是:ActivityFragment 创建后、使用这些字段之前调用,通常放在 onCreate()setContentView() 之后最合适。


六、Fragment 跳转

例如:

Fragment fragment =
(Fragment) ARouter.getInstance()
        .build("/home/fragment")
        .navigation();

对应:

@Route(path="/home/fragment")
public class HomeFragment extends Fragment{

}

七、Service 获取

例如:

定义接口:

public interface IUserService {

    String getUserName();
}

实现:

@Route(path = "/service/user")
public class UserServiceImpl implements IUserService {

    @Override
    public String getUserName() {
        return "Tom";
    }
}

获取:

IUserService service =
(IUserService) ARouter.getInstance()
        .build("/service/user")
        .navigation();

service.getUserName();

模块之间无需直接依赖实现类。


八、拦截器(Interceptor)

可以统一处理登录校验、权限等。

例如:

订单页面
      │
      ▼
Interceptor
      │
      ├──已登录
      │      │
      │      ▼
      │   OrderActivity
      │
      └──未登录
             │
             ▼
      LoginActivity

定义:

@Interceptor(priority = 1)
public class LoginInterceptor implements IInterceptor {

    @Override
    public void process(Postcard postcard,
                        InterceptorCallback callback) {

        if (isLogin()) {
            callback.onContinue(postcard);
        } else {
            callback.onInterrupt(null);
        }
    }
}

九、自动注入(Autowired)

例如:

@Autowired
String token;

其实最终还是:

getIntent().getStringExtra("token");

只是 ARouter 帮你生成了代码。


十、Provider(推荐)

大型项目中最常用。

例如:

UserModule

提供:

获取 Token

获取用户信息

退出登录

其他模块:

Order

Home

Message

都可以:

ARouter

↓

UserProvider

无需依赖 User 模块。


十一、初始化

Application:

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        if (BuildConfig.DEBUG) {
            ARouter.openLog();
            ARouter.openDebug();
        }

        ARouter.init(this);
    }
}

调试模式:

ARouter.openLog();

ARouter.openDebug();

正式版建议关闭。


十二、编译时原理(重点)

ARouter 最大优势之一是 编译时生成路由表,而不是运行时反射扫描。

例如:

@Route(path="/login/main")
public class LoginActivity {}

编译期间,APT(Annotation Processing)会生成类似代码:

public class ARouter$$Group$$login
        implements IRouteGroup {

    @Override
    public void loadInto(Map<String, RouteMeta> atlas) {

        atlas.put(
            "/login/main",
            RouteMeta.build(
                LoginActivity.class
            )
        );
    }
}

初始化时:

Warehouse.routes

中保存:

"/login/main"
        │
        ▼
LoginActivity.class

调用:

navigation()

时:

String Path
        │
        ▼
HashMap
        │
        ▼
Activity.class
        │
        ▼
Intent

因此查找速度快,避免了运行时大量反射。


十三、完整使用示例

// 定义页面
@Route(path = "/user/detail")
public class UserActivity extends AppCompatActivity {

    @Autowired
    String name;

    @Autowired
    int age;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ARouter.getInstance().inject(this);

        Log.d("TAG", name);
        Log.d("TAG", age + "");
    }
}

跳转:

ARouter.getInstance()
        .build("/user/detail")
        .withString("name", "Tom")
        .withInt("age", 18)
        .navigation(this);

十四、ARouter 的优缺点

优点缺点
页面解耦学习成本比 Intent
支持组件化需要配置注解处理器(APT/KSP)
支持参数自动注入项目规模小时收益不明显
支持拦截器官方维护已不如早期活跃
支持 Service/Provider新项目有时会选择其他路由方案

面试高频问题

  1. ARouter 为什么比直接使用 Intent 更适合大型项目?

    • 通过路径而非类引用进行跳转,降低模块间依赖,利于组件化和模块化开发。
  2. ARouter.getInstance().inject(this) 有什么作用?什么时候调用?

    • 用于解析 @Autowired 标注的字段并完成参数注入,应在 Activity/Fragment 创建完成后、使用这些字段之前调用,通常放在 onCreate() 中。
  3. ARouter 底层为什么性能较好?

    • 使用注解处理器在编译期生成路由映射表,运行时直接查询映射并构建 Intent,避免了运行时扫描和大量反射。
  4. ARouter 可以路由哪些组件?

    • 不仅支持 Activity,还支持 FragmentService/Provider,并提供拦截器、参数注入等能力。

如果你现在主要做 Android 面试,我还可以继续讲 ARouter 源码(路由表生成、WarehouseLogisticsCenterPostcardnavigation() 源码流程),这是高级 Android 面试中非常常见的考点。