ARouter source code analysis

arouter-api version : 1.4.1


So far, ARouter has not resolved the final dependency injection, so today we will explore its implementation principle.

PS: because the principle of dependency injection is relatively simple, this article will be short.

@Autowired parsing

To implement dependency injection with ARouter, you need to add


Then our code becomes the entry point for our analysis.

public void inject(Object thiz) {

ARouter is still called internally_ The inject method of ARouter.

static void inject(Object thiz) {
    AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
    // If autowiredService is not empty, complete dependency injection
    if (null != autowiredService) {

It is found that dependency injection is very similar to interceptors, which are completed by using service components. The service component of dependency injection is called AutowiredService. Tracing shows that its implementation class is AutowiredServiceImpl.

@Route(path = "/arouter/service/autowired")
public class AutowiredServiceImpl implements AutowiredService {
    private LruCache<String, ISyringe> classCache;
    private List<String> blackList;

    public void init(Context context) {
        classCache = new LruCache<>(66);
        blackList = new ArrayList<>();

    public void autowire(Object instance) {
        String className = instance.getClass().getName();
        try {
            // If the instance class is blacklisted, dependency injection will not be completed
            if (!blackList.contains(className)) {
                // Get from cache first
                ISyringe autowiredHelper = classCache.get(className);
                // Create object without cache
                if (null == autowiredHelper) {  // No cache.
                    autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
                // Complete dependency injection
                // Put in cache
                classCache.put(className, autowiredHelper);
        } catch (Exception ex) {
            // Add to the blacklist if there is an error
            blackList.add(className);    // This instance need not autowired.

ISyringe is the interface extracted by dependency injection,

public interface ISyringe {
    void inject(Object target);

So who is the implementation class of ISyringe? The answer is the class XXXX automatically generated at compile time


Autowired, let's find the Test1Activity generated in the demo


Autowired take a look

public class Test1Activity$$ARouter$$Autowired implements ISyringe {
  private SerializationService serializationService;

  public void inject(Object target) {
    serializationService = ARouter.getInstance().navigation(SerializationService.class);
    Test1Activity substitute = (Test1Activity)target; = substitute.getIntent().getStringExtra("name");
    substitute.age = substitute.getIntent().getIntExtra("age", substitute.age);
    substitute.height = substitute.getIntent().getIntExtra("height", substitute.height);
    substitute.girl = substitute.getIntent().getBooleanExtra("boy", substitute.girl); = substitute.getIntent().getCharExtra("ch",;
    substitute.fl = substitute.getIntent().getFloatExtra("fl", substitute.fl);
    substitute.dou = substitute.getIntent().getDoubleExtra("dou", substitute.dou);
    substitute.ser = ( substitute.getIntent().getSerializableExtra("ser");
    substitute.pac = substitute.getIntent().getParcelableExtra("pac");
    if (null != serializationService) {
      substitute.obj = serializationService.parseObject(substitute.getIntent().getStringExtra("obj"), new<TestObj>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'obj' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
    if (null != serializationService) {
      substitute.objList = serializationService.parseObject(substitute.getIntent().getStringExtra("objList"), new<List<TestObj>>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'objList' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
    if (null != serializationService) { = serializationService.parseObject(substitute.getIntent().getStringExtra("map"), new<Map<String, List<TestObj>>>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'map' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
    substitute.url = substitute.getIntent().getStringExtra("url");
    substitute.helloService = ARouter.getInstance().navigation(HelloService.class);

From the automatically generated code above, we can see that dependency injection actually uses getintent internally Getxxxextra (similarly, Fragment uses getarguments () getXxx() ). It should be noted that the field modified by @Autowired cannot be private, otherwise an error will be reported when automatically generating code.

In addition, what is a SerializationService used for in the above code? In fact, SerializationService is used for json serialization. In the demo, an implementation class JsonServiceImpl is officially given, and Alibaba's fastjson is used internally. If you need to customize children's shoes, you can refer to JsonServiceImpl to implement it yourself.


Seeing this, basically, we have finished talking about ARouter dependency injection.

In this series, the process of ARouter code level is almost the same. The remaining two parts are gradle plugin and compiler, which have not been parsed yet. I will tell you later.

bye bye

Posted by bh on Mon, 01 Aug 2022 22:55:46 +0530