ARouter源码解析05-自动参数注入
来源:互联网 发布:搜歌词的软件 编辑:程序博客网 时间:2024/06/03 03:12
这篇文章来分析ARouter的自动参数注入
以ARouter示例程序中的BlankFragment为例
@Route(path = "/test/fragment")public class BlankFragment extends Fragment { @Autowired String name; @Autowired(required = true) TestObj obj; public BlankFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); return textView; }}
在编译的时候,会在app/build/generated/source/apt/debug/com.alibaba.android.arouter/
生成BlankFragment$$ARouter$$Autowired
public class BlankFragment$$ARouter$$Autowired implements ISyringe { private SerializationService serializationService; @Override public void inject(Object target) { serializationService = ARouter.getInstance().navigation(SerializationService.class);; BlankFragment substitute = (BlankFragment)target; substitute.name = substitute.getArguments().getString("name"); if (null != serializationService) { substitute.obj = serializationService.json2Object(substitute.getArguments().getString("obj"), TestObj.class); } }}
即,调用inject(),就会将参数进行赋值。
那么,什么时候调用的inject()呢?
在 InstrumentationHook这个类中,会去判断是否是可以自动inject的,如果autdoInject标记为true,则会通过反射来调用相关Autowired的inject()方法。但是,在这个类已经被标记为Deprecated,注释提示我们现在使用ARouter.getInstance().inject(this)
,同时查看官方文档,也是需要手动使用inject()来进行参数注入。
/** * Use ARouter.getInstance().inject(this) now! * * Hook the instrumentation, inject values for activity's field. * Support normal activity only, not contain unit test. * * @author Alex <a href="mailto:zhilong.liu@aliyun.com">Contact me.</a> * @version 1.0 * @since 2016/11/24 16:42 */@Deprecatedpublic class InstrumentationHook extends Instrumentation { /** * Hook the instrumentation's newActivity, inject * <p> * Perform instantiation of the process's {@link Activity} object. The * default implementation provides the normal system behavior. * * @param cl The ClassLoader with which to instantiate the object. * @param className The name of the class implementing the Activity * object. * @param intent The Intent object that specified the activity class being * instantiated. * @return The newly instantiated Activity object. */ public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException {// return (Activity)cl.loadClass(className).newInstance(); Class<?> targetActivity = cl.loadClass(className); Object instanceOfTarget = targetActivity.newInstance(); if (ARouter.canAutoInject()) { String[] autoInjectParams = intent.getStringArrayExtra(ARouter.AUTO_INJECT); if (null != autoInjectParams && autoInjectParams.length > 0) { for (String paramsName : autoInjectParams) { Object value = intent.getExtras().get(TextUtils.getLeft(paramsName)); if (null != value) { try { Field injectField = targetActivity.getDeclaredField(TextUtils.getLeft(paramsName)); injectField.setAccessible(true); injectField.set(instanceOfTarget, value); } catch (Exception e) { ARouter.logger.error(Consts.TAG, "Inject values for activity error! [" + e.getMessage() + "]"); } } } } } return (Activity) instanceOfTarget; }}
没错,现在的ARouter的自动参数注入需要手动调用ARouter.getInstance().inject()。
再来看ARouter.getInstance().inject(),最终会调用AutowiredServiceImpl的autowire方法
@Route(path = "/arouter/service/autowired")public class AutowiredServiceImpl implements AutowiredService { private LruCache<String, ISyringe> classCache; private List<String> blackList; @Override public void init(Context context) { classCache = new LruCache<>(66); blackList = new ArrayList<>(); } @Override public void autowire(Object instance) { String className = instance.getClass().getName(); try { if (!blackList.contains(className)) { ISyringe autowiredHelper = classCache.get(className); if (null == autowiredHelper) { // No cache. autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance(); } autowiredHelper.inject(instance); classCache.put(className, autowiredHelper); } } catch (Exception ex) { blackList.add(className); // This instance need not autowired. } }}
可以看到,autowire()中,会通过反射,调用我们上面提到的IDE自动生成的BlankFragment$$ARouter$$Autowired
这个类的inject()
然后在inject()中,再进行赋值,这样就完成了自动注入的过程。
至此,我们分析完了ARouter的自动参数注入。
阅读全文
0 0
- ARouter源码解析05-自动参数注入
- ARouter 依赖注入实现原理(源码解析)
- ARouter源码解析06-openDebug
- 阿里路由框架--ARouter 源码解析之初始化ARouter
- ARouter源码解析01-编译生成文件
- ARouter源码解析02-加载路由表单
- ARouter源码解析03-路由跳转
- ARouter源码解析04-interceptor拦截器
- [源码]ARouter
- ARouter解析一:基本使用及页面注册源码解析
- 阿里路由框架--ARouter 源码解析之Compiler
- 阿里ARouter源码分析
- ARouter
- Spring源码解析 依赖注入
- Spring源码解析 依赖注入
- Spring源码解析 依赖注入
- 【Hibernate实战】源码解析Hibernate参数绑定及PreparedStatement防SQL注入原理
- ARouter源码分析初始化以及跳转
- 每日一题——子树
- webview--连接百度
- 排列 permutation 算法竞赛入门经典第二版 习题2-6
- jdbc+sql+preparedStatement使用预编译实现增添数据
- java单元测试之如何实现异步接口的测试案例
- ARouter源码解析05-自动参数注入
- 对于订餐系统的一些扩展的感受
- JavaScript高级程序设计(1-2)
- Hadoop-2.7.2集群的搭建——集群学习日记
- RPC框架原理简介
- 数值转换格式
- WebView 中 H5 页面的软键盘遮挡输入框
- Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别
- 关注民生民情——华北水利水电大学“情艺”小孟庄社区调查