美文网首页
ARouter源码分析-依赖注入

ARouter源码分析-依赖注入

作者: dashingqi | 来源:发表于2020-07-25 14:50 被阅读0次
    Android_Banner.jpg

    简介

    • 该篇文章是ARouter源码分析的最后一篇文章了,使用依赖注入在页面跳转中进行数据的传递

    基本使用

    • 测试代码
    mBtnTestAutoired.setOnClickListener(view -> {
                ARouter.getInstance().build("/test/test2")
                        .withString("id", "1922321321")
                        .withString("name", "dashingqi")
                        .navigation();
            });
    
    
    
    @Route(path = "/test/test2")
    public class MyAutoriedActivity extends AppCompatActivity {
    
        private static final String TAG = "MyAutoriedActivity";
    
        @Autowired
        String name = "";
    
        @Autowired
        String id = "";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my_autoried);
            ARouter.getInstance().inject(this);
    
            Log.d(TAG, "onCreate: name = " + name);
            Log.d(TAG, "onCreate: id = " + id);
    
        }
    }
    

    原理分析

    在上述的ARouter依赖注入的使用中,最关键的两点就是

    1. 在目标页面中,使用了@Autowired注解,
    2. 在目标页面 调用了ARouter的inject()注入了当前的目标页面(ARouter.getInstance().inject(this))
    • ARouter().getInstance().inject(this)
     public void inject(Object thiz) {
            _ARouter.inject(thiz);
        }
    
    • _ARouter #inject()
    static void inject(Object thiz) {
            // 通过IoC的ByName形式获取到实例
            //AutowiredService是一个接口继承 IProvider
            // "/arouter/service/autowired" 该路由地址是作用于 AutowiredServiceImpl类上
            // 它是AutowiredService接口的唯一实现子类
            AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
            if (null != autowiredService) {
                //此处调用了AutowiredServiceImpl的autowired()方法
                autowiredService.autowire(thiz);
            }
        }
    
    • AutowiredServiceImpl # autowire()
    @Override
        public void autowire(Object instance) {
        //首先获取到对象的Class对象的名字
            String className = instance.getClass().getName();
            try {
                // 当blackList中没有存储 className的映射关系
                if (!blackList.contains(className)) {
                    // 从classCache 缓存中查找
                    ISyringe autowiredHelper = classCache.get(className);
                    //缓存中不存在
                    if (null == autowiredHelper) {  
                        //通过反射获取到实例,我们可以看出获取实例对应的全限定名是 类名$$ARouter$$Autowired
                        //其实这个类是在编译期间就已经生成好了
                        // 
                        autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
                    }
                    //  执行了该实例的inject()方法
                    autowiredHelper.inject(instance);
                    classCache.put(className, autowiredHelper);
                }
            } catch (Exception ex) {
                blackList.add(className);    // This instance need not autowired.
            }
        }
    
    • 看下在编译期间我们自动生成的代码中inject()
    public class MyAutoriedActivity$$ARouter$$Autowired implements ISyringe {
      private SerializationService serializationService;
    
      @Override
      public void inject(Object target) {
        
        serializationService = ARouter.getInstance().navigation(SerializationService.class);
        //强转成我们的目标类
        MyAutoriedActivity substitute = (MyAutoriedActivity)target;
        // 拿数据
        substitute.name = substitute.getIntent().getStringExtra("name");
        //给变量赋值数据
        substitute.id = substitute.getIntent().getStringExtra("id");
      }
    }
    

    相关文章

      网友评论

          本文标题:ARouter源码分析-依赖注入

          本文链接:https://www.haomeiwen.com/subject/sqlncktx.html