写点什么

不要总是相信 @JvmOverloads,安卓开发指南

作者:嘟嘟侠客
  • 2021 年 11 月 28 日
  • 本文字数:2204 字

    阅读完需:约 7 分钟

class CustomLinearLayout @JvmOverloads constructor(


context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0


) : LinearLayout(context, attrs, defStyleAttr)


第 0 步:出现的问题




我们先来看看Design库中的TextInputEditText控件,


在我们自定义类中,如下:


class CustomTextInputEditText : TextInputEditText {


constructor(context: Context) : super(context)


constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)


constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)


}


上面的代码可以通过一个构造函数来替换:


class CustomTextInputEditText @JvmOverloads constructor(


context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0


) : TextInputEditText(context, attrs, defStyleAttr)


这也是 Android Studio 会自动为我们生成的代码


!](https://upload-images.jianshu.io/upload_images/15679108-d208f39b8eb1877c?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


接下来我们写一个 Activity,它有两个CustomTextInputEditText?控件,第一个包含所有三个构造函数,第二个包含?@JvmOverloads注释。


class CustomTextInputEditText1 : TextInputEditText {


constructor(context: Context) : super(context)


constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)


constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)


}


class CustomTextInputEditText2 @JvmOverloads constructor(


context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0


) : TextInputEditText(context, attrs, defStyleAttr)


它们的表现最终会相同吗?


[外链图片转存失败(img-jtjcLWwA-1569229719416)(https://upload-images.jianshu.io/upload_images/15679108-f64a5b1fa110e916?imageMogr2/auto-orient/strip)]


正如你所看到的,第二个使用@JvmOverloads注解的控件没有工作。


发生了什么?为什么会有一些样式问题?


[外链图片转存失败(img-NBnEi2L8-1569229719418)(https://upload-images.jianshu.io/upload_images/15679108-0b77b50c7a77c58b?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]


第 1 步: 理解@JvmOverloads注解




让我们再花 1 秒钟回看一下JvmOverloads?的定义,我们知道 Kotlin 编译器会产生两个重载(在我们的例子中N = 3M = 2)。所以我们最终会得到三个类似的构造函数:


@JvmOverloads


public CustomTextInputEditText(@NotNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {


super(context, attrs, defStyleAttr);


}


@JvmOverloads


public CustomTextInputEditText(@NotNull Context context, @Nullable AttributeSet attrs) {


this(context, attrs, 0);


}


@JvmOverloads


public CustomTextInputEditText(@NotNull Context context) {


this(context, null, 0);


}


因此在我们的自定义类中,我们总是会调用到CustomTextInputEditText三参数构造函数。


第 2 步:理解 View 的构造函数




现在让我们暂时关注到 View 的构造函数。


当 View 从 XML 文件中加载时,会调用其第二个构造函数。然后,此构造函数调用三参数构造函数。


public View(Context context, @Nullable AttributeSet attrs) {


this(context, attrs, 0);


}


如果通常将0作为第三个参数,为什么这个三参数构造函数要存在呢?答案在文档中。


View 的这个构造函数允许子类在加载时使用它们自己的基本样式。


继承自 View 的类可以传递它们自己的样式来修改所有基本view属性。


简单,现在我们来看看为什么会出错。


第 3 步:了解到底哪儿出了问题




此时,从第1步开始,我们知道由于@JvmOverloads注解,我们总是调用一个三参数构造函数,而从第2步开始,继承自 View 的类可以使用这个三参数构造函数来传递它们自己的样式。


让我们回到TextInputEditText的构造函数来看看,特别是第二个:


public TextInputEditText(Context context, AttributeSet attrs) {


this(context, attrs, attr.editTextStyle);


}

最后

光有这些思路和搞懂单个知识的应用是还远远不够的,在 Android 开源框架设计思想中的知识点还是比较多的,想要搞懂还得学会整理和规划:我们常见的**Android 热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava 响应式编程框架、IOC 依赖注入框架、最近架构组件 Jetpack 等等 Android 第三方开源框架,**这些都是属于 Android 开源框架设计思想的。如下图所示:



这位阿里 P8 大佬针对以上知识点,熬夜整理出了一本长达 1042 页的完整版如何解读开源框架设计思想 PDF 文档,内容详细,把 Android 热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava 响应式编程框架、IOC 依赖注入框架、最近架构组件 Jetpack 等等 Android 第三方开源框架这些知识点从源码分析到实战应用都讲的简单明了。


**由于文


《Android 学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享


档内容过多,篇幅受限,只能截图展示部分**




整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~


你的支持,我的动力;祝各位前程似锦,offer 不断!!!


本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

用户头像

嘟嘟侠客

关注

还未添加个人签名 2021.03.19 加入

还未添加个人简介

评论

发布
暂无评论
不要总是相信 @JvmOverloads,安卓开发指南