ARouter 之注解 @JvmField 和 @Autowired

2023-11-16

1. 定义

  • 在 Activity 进行数据传递一般都会通过 getIntent().putxxx()/getxxx() 方法;在 Fragment 中进行数据传递一般都会通过 getArguments().getxxx() 方法,如果传递的字段过多,可能会写很多个取值语句。为了简化这些繁琐的步骤,ARouter 提供了使用注解的方式来完成参数的注入,这是通过 @Autowired 来实现的。
/**
 * Annotation for field, which need autowired.
 *
 * @author zhilong <a href="mailto:zhilong.lzl@alibaba-inc.com">Contact me.</a>
 * @version 1.0
 * @since 2017/2/20 下午4:26
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface Autowired {

    // Mark param's name or service name.
    String name() default "";

    // If required, app will be crash when value is null.
    // Primitive type wont be check!
    boolean required() default false;

    // Description of the field
    String desc() default "";
}
  • name():定义了属性获取值的 key
  • required():定义了当前属性是否是必须的,默认为 false。如果是必须的,但是值为 null,APP 会 crash。基本类型不会做 null 校验。
  • desc():字段说明

2. 使用

  • 若属性名保持一致,name 可不加
@Autowired(name = "isForFreeVip")
var isForFreeVip = false
  • 对应生成的注解文件:
/**
 * DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
public class KGLoginActivity$$ARouter$$Autowired implements ISyringe {
  private SerializationService serializationService;

  @Override
  public void inject(Object target) {
    serializationService = ARouter.getInstance().navigation(SerializationService.class);
    KGLoginActivity substitute = (KGLoginActivity)target;
    // isForFreeVip 不加 @JvmFiled 注解的话,是 private 遍历,无法通过下面的方式访问到,必须通过 setForFreeVip() 去赋值,那在此处就会赋值失败
    substitute.isForFreeVip = substitute.getIntent().getBooleanExtra("isForFreeVip", substitute.isForFreeVip);
  }
}
  • 赋值操作在 inject() 方法中,这个方法的调用链如下:ARouter.inject() -> _ARouter.inject() -> AutowiredServiceImpl.autowire() -> ISyringe.inject(Object)

3. 源码分析

  • 之前说过的调用链是:ARouter.inject() -> _ARouter.inject() -> AutowiredServiceImpl.autowire() -> ISyringe.inject()

  • ARouter.inject()

public void inject(Object thiz) {
    _ARouter.inject(thiz);
}
  • _ARouter.inject()
static void inject(Object thiz) {
    // 去路由表里查找 "/arouter/service/autowired" 的实现类,就是 AutowiredServiceImpl
    AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
    if (null != autowiredService) {
        autowiredService.autowire(thiz);
    }
}
  • 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();
                }
               
                // 就是编译期生成的 XXX$$ARouter$$Autowired 文件中的 inject 方法
                autowiredHelper.inject(instance);
                // 将实例对象缓存起来
                classCache.put(className, autowiredHelper);
            }
        } catch (Exception ex) {
            // 如果发生异常,加入黑名单
            blackList.add(className);    // This instance need not autowired.
        }
    }
}

4. 为什么 @Autowired 要搭配 @JvmFiled 同时使用?

  • ARouter 对 kotlin 中的 @Autowired 注解赋值,为什么需要对变量用 @JvmFiled 标记?

  • @JvmFiled 的作用:不加 @JvmFiled 默认就会生成 setter() 和 getter() 方法,赋/取值操作实际上是调用 setter() 和 getter(),而变量本身对 java 代码是不可见的,可以认为是 private。使用 @JvmField 标记后,反编译后的 java 代码中发现,不会再自动生成对应的 setter() 和 getter() 方法,此时变量对 java 代码也是可见的。

  • 查看源码 com.alibaba.android.arouter.core.AutowiredServiceImpl#autowire() 方法中,通过反射获取变量名并进行赋值,但是反射时并没有设置 setAccessible(true)【这句话的作用是允许访问私有变量】,不能访问私有变量,从而导致赋值失败

  • 去掉 @JvmFiled 反编译后的结果:

@Autowired
private boolean isForFreeVip;

public final boolean isForFreeVip() {
  return this.isForFreeVip;
}

public final void setForFreeVip(boolean var1) {
  this.isForFreeVip = var1;
}
  • 加上 @JvmFiled 反编译后的结果:
@JvmField
@Autowired
public boolean isForFreeVip;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ARouter 之注解 @JvmField 和 @Autowired 的相关文章

  • PHP服务器端IAB验证openssl_verify总是返回0

    我使用以下函数 服务器端 php 来验证 IAB v3 事务 我从 Android 应用程序传递过来 Override protected void onActivityResult int requestCode int resultCo
  • Android:如何从输入流创建 9patch 图像?

    我使用下面的代码实例化 9patch 图像并将其设置为按钮的背景 下图显示了不理想的结果 InputStream MyClass class getResourceAsStream images btn default normal 9 p
  • NumberPicker 的格式化值在单击时消失

    我的 NumberPicker 在setDescendantFocusability FOCUS BLOCK DESCENDANTS 模式和setWrapSelectorWheel false 已关闭 我用一个简单的格式化程序格式化了我的
  • Android:拍照后调用裁剪活动

    我在解析拍摄照片的 uri 来裁剪活动时遇到问题 在我的应用程序中 用户可以拍摄一张照片或从图库中选择一张照片 然后裁剪并上传 一切听起来都很简单 从图库中选择时 图库应用程序会返回所选照片的 uri 如下所示 content media
  • 无法从 com.android.aaptcompiler.ParsedResource@ef79973 提取资源

    无法从 com android aaptcompiler ParsedResource ef79973 提取资源 无法从 com android aaptcompiler ParsedResource 4c95ce87 提取资源 C Use
  • 返回主要活动(意图)时传递数据我做错了什么?

    我是安卓新手 这可能是最简单的问题 但我不明白这里出了什么问题 我试图创建一个通过意图传递值的基本示例 因此 当我关闭第二个活动时 我需要将数据传递到主活动 这是代码 意图测试1 主要活动 public void onClick View
  • Android 性能:SharedPreferences 的成本

    当我的应用程序启动时 我使用分片首选项中的值填充容器类 这个想法是处理 SharedPreferences 和 PreferenceManager 一次 因为我猜它们很重 这是一个示例 SharedPreferences prefs Pre
  • 如何在虚拟机 VirtualBox 上运行 Android-x86 4.2 iso?

    我想用Android x86测试和调试我的应用程序 我之前成功尝试过其他版本的Android x86 但是关于android x86 4 2有一个错误 所以我在这里问我的问题 因为它可能会发生在其他人身上 我安装了oracle VM vir
  • cordova插件条码扫描仪打不开扫描

    我的条形码扫描仪插件有问题 我不是天才 我不太了解如何编写网络应用程序 我使用phonegap和cordova 并且尝试制作一个网络应用程序 在单击链接后扫描条形码 我之前已经使用此命令行安装了该插件 cordova plugin add
  • 如何从webkit浏览器中检测Android版本和品牌?

    如何通过webkit浏览器检测Android版本和品牌 可靠吗 我相信你可以检查用户代理 但是 我认为它不安全 因为有很多方法可以用来欺骗用户代理 在谷歌上搜索这个问题给了我们很多答案 它甚至可以在默认浏览器上运行 您只需输入 about
  • Android 发布到 facebook 墙,stream.publish 几天来就中断了

    我有很多使用 FB android sdk 发布的应用程序 github com facebook facebook android sdk 我所有使用 FB 的应用程序几天后就停止工作了 这必然是 FB 方面的更改或错误 因为我的应用程序
  • 使用 cordova cli 构建时的 Android 安装位置

    我正在使用 cordova CLI 工具构建一个大型 cordova phonegap 应用程序 我需要 AndroidManifest xml 文件中的 installLocation 具有 installLocation auto 或p
  • 确定视图是否在屏幕上 - Android

    我对这个有点困惑 首先也是最重要的是 以下链接很有用 但是我提出了一些可见性问题 链接 检查视图可见性 https stackoverflow com questions 4628800 android how to check if a
  • 在 Android ADT Eclipse 插件中滚动布局编辑器

    有谁知道当布局编辑器的内容溢出一个 屏幕 时如何滚动这些内容 我说的是在设计时使用 ADT 布局编辑器 而不是在物理设备上运行时滚动 效果很好 关闭 Android 布局编辑器中的剪辑 切换剪辑 按钮位于 Android 布局编辑器的右上角
  • BadPaddingException:无效的密文

    我需要一些帮助 因为这是我第一次编写加密代码 加密代码似乎工作正常 但解密会引发错误 我得到的错误是 de flexiprovider api exceptions BadPaddingException 无效的密文 in the 解密函数
  • 从多个 TextView 中选择文本

    如何在android中从多个文本视图中选择文本 我已经尝试过以下代码 该代码一次仅适用于一个文本视图 我想一次性从许多文本视图中复制文本 android textIsSelectable true 你不能同时这样做 您需要在单个文本视图中设
  • Android UnityPlayerActivity 操作栏

    我正在构建一个 Android 应用程序 其中包含 Unity 3d 交互体验 我已将 Unity 项目导入 Android Studio 但启动时该 Activity 是全屏的 并且不显示 Android 操作栏 我怎样才能做到这一点 整
  • firebase中按范围查询

    我有一个食品价格范围滑块 根据滑块的最小值和最大值 我想显示此范围内的食品 滑块代码 multiSlider setOnThumbValueChangeListener new MultiSlider SimpleChangeListene
  • Android中绑定适配器有什么用?

    我一直在阅读有关Android中绑定适配器的文章 但我似乎不明白它 何时使用绑定适配器 有人可以用一个简单的例子来解释它吗 我读过的一篇文章在主活动中有一个绑定适配器 绑定适配器有一个参数 toastMessage 显然 只要 toastM
  • 如何让用户在android列表视图中选择主题?

    我有一个带有两个标签的列表视图 标题和副标题 我想要深色和浅色背景作为用户选项 标题具有 textAppearanceMedium 副标题具有 textAppearanceSmall 我希望样式 MyTheme Dark 具有白色文本 My

随机推荐

  • java.lang.ArrayIndexOutOfBoundsException(数组越界)处理方法

    转发自https blog csdn net qq 34646449 article details 76146659 当你使用不合法的索引访问数组时会报数组越界这种错误 数组arr的合法错误范围是 0 arr length 1 当你访问这
  • 使用反射动态校验后台配置某字段是否允许为空

    背景 使用easyExcel读取数据 title不固定 后台可以配置title必填项 title顺序可改变 用户可以自定义title 不存储自定义信息即可 不报错 思路 不能使用easyExcel使用index的方式读取数据 改成value
  • 文件在使用FileChannel.map后不能被删除(Windows上)

    同事发现在Windows上使用FileChannel的map方法之后 不能够删除掉文件 我在Linux上试了一下 发现没这个问题 做个笔记 记录一下 import java io File import java io RandomAcce
  • Unity笔记之获取鼠标停留的UI和删除按键触发后引用、判断鼠标是否在UI上

    需求 鼠标放在UI上 需要获取这个UI物体 以方便进行其他操作 百度学习了半天 最终拿了一个大哥 添加链接描述 的内容 本文仅作为个人笔记 建议大家直接去这大哥的博客看 不过我记得好像也可以通过继承unity内部的鼠标事件接口获取到物体 但
  • java.io.StreamCorruptedException: invalid type code: AC错误解决

    最近做IO时 出现了一个我百思不得其解的错误 虽然经过一番 解决的bug 但是对于这一方面的底层知识还是有待去深入了解 借这个机会 好好学习一下 一般 可以使用ObjectInputStream把对象写出到文件 再使用ObjectOutpu
  • 五分钟告诉你什么是爬虫?

    1 什么是爬虫 把互联网比喻成一张网 那么爬虫就是网上爬行的蜘蛛 把网的节点比喻成一个个网页 爬虫爬取到就相当于访问了该页面 获取了其信息 爬虫可以通过一个节点之后 顺着节点连线 链接 继续爬行到下一个节点 即通过一个网页继续获取后续的网页
  • 直播 RTM 推流在抖音的应用与优化

    动手点关注 干货不迷路 背景 随着互联网技术以及网络基建的快速发展和普及 视频直播已经成为了一种越来越普遍的娱乐和社交方式 无论是个人还是企业 都可以通过视频直播平台进行直播活动 向观众展示自己的生活 工作或者产品 同时 视频直播也成为了一
  • sqlmap自动注入1(Target完整的超级详细 如有错误望指出)

    SQLmap的自动注入学习之路 1 是通过五种sql注入漏洞的检测技术 and select from select sleep 20 a 这是基于时间的盲注检测 看他返回的时间 可以在DVWA试试 sqlmap支持非常全面的 数据库管理系
  • 咬了一口苹果死去的计算机之父——图灵

    艾伦 麦席森 图灵 Alan Mathison Turing 1912年6月23日 1954年6月7日 英国数学家 逻辑学家 被称为计算机科学之父 人工智能之父 1910年左右的伦敦 1912年生于英国伦敦帕丁顿 家族成员里有三位当选过英国
  • 星网宇达-组合导航在ros系统中的使用方法

    1 安装差分天线 两个 组合导航主机 DTU模块 不使用基站GPS的定位精度是米级的 园区里面自己搭建基站用DTU进行数据传输精度可达到厘米级 也可以利用千寻基站进行定位 效果不清楚 2 根据 杆臂以及天线安装说明文档 进行天线安装和杆臂配
  • 数据分析03——矩阵常用计算方法和函数

    0 前言 数组 计算机领域的概念 矩阵 数学领域的概念 对于Numpy而言 矩阵是数组的分支 1 创建矩阵 字符串创建矩阵 mat1 np matrix 1 2 3 4 列表形式创建矩阵 mat2 np matrix 5 6 7 8 通过数
  • QTextDocument和QTextBlock

    QTextDocument QTextDocument是用于结构化富文本文档的容器 为样式文本和各种类型的文档元素 如列表 表格 框架和图像 提供支持 可以创建它们以在QTextEdit中使用 也可以独立使用 每个文档元素均由关联的格式对象
  • 可视化工具Netron介绍

    Netron是一种用于神经网络 深度学习和机器学习模型的可视化工具 它可以为模型的架构生成具有描述性的可视化 descriptive visualization 源码在 https github com lutzroeder netron
  • Taro安装、启动命令、创建项目、修改端口号以及如何在微信开发者工具内运行

    1 安装Taro开发工具 npm install g tarojs cli 或者yarn global add tarojs cli 使用npm可能会有一些报错的信息 建议使用cnpm安装 2 使用命令创建模板 taro init myAp
  • 教你如何基于Redis来实现高性能延时消息队列!

    最近在倒腾自建博客后端系统 需要用到延时任务的功能 但手头只有一套MySQL和Redis 如果搞一套MQ成本有点大 于是想着用redis实现延时消息队列 有些场景用数据库的定时扫表也能简单实现延时消息的功能 不过对于我这边的实际场景 比如计
  • C#学习笔记 任务操作

    利用线程 可以方便地进行异步操作 但是线程模型有一个缺点 就是无法处理返回值 要在不同线程之间传递数据比较麻烦 任务则解决了这个问题 完整代码在这里 https github com techstay csharp learning not
  • 流程控制和数组(下)

    文章目录 Java 类 Arrays Java 类 Arrays Java提供的Arrays类里包含的一些statics修饰的方法可以直接操作数组 这个Arrays类里包含了如下的几个static修饰的方法 static修饰的方法可以直接通
  • 【数据挖掘】数据清洗

    数据挖掘 数据清洗 数据挖掘一般流程 数据挖掘一般流程 需求分析 数据挖掘任务分类 1 预测 分类 回归 2 聚类 文档归类 3 关联性分析 购物篮分析 4 异常检测 信用卡欺诈 获取数据 sql linux 爬虫 数据清洗 主要 去重 缺
  • Halcon极坐标变换检测缺陷

    一 原图 二 通过极性变换拉直 三 检测缺陷 This example checks bottle necks for defects First the bottle is detected with basic morphology e
  • ARouter 之注解 @JvmField 和 @Autowired

    文章目录 1 定义 2 使用 3 源码分析 4 为什么 Autowired 要搭配 JvmFiled 同时使用 1 定义 在 Activity 进行数据传递一般都会通过 getIntent putxxx getxxx 方法 在 Fragme