简介
- 该篇文章是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依赖注入的使用中,最关键的两点就是
- 在目标页面中,使用了@Autowired注解,
- 在目标页面 调用了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");
}
}
网友评论