不要总是相信 @JvmOverloads,安卓开发指南
class CustomLinearLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr)
我们先来看看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 会自动为我们生成的代码
接下来我们写一个 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
?的定义,我们知道 Kotlin 编译器会产生两个重载(在我们的例子中N = 3
和M = 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
三参数构造函数。
现在让我们暂时关注到 View 的构造函数。
当 View 从 XML 文件中加载时,会调用其第二个构造函数。然后,此构造函数调用三参数构造函数。
public View(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
如果通常将0
作为第三个参数,为什么这个三参数构造函数要存在呢?答案在文档中。
View 的这个构造函数允许子类在加载时使用它们自己的基本样式。
继承自 View 的类可以传递它们自己的样式来修改所有基本view
属性。
简单,现在我们来看看为什么会出错。
此时,从第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 不断!!!
评论