最全Android---Fragment-的过去、现状与未来(1),2024年最新Android开发面试准备

学习福利

【Android 详细知识点思维脑图(技能树)】

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

val scenario = launchFragmentInContainer()
scenario.moveToState(State.CREATED)
}

@Test
fun testEventFragment() {
val scenario = launchFragmentInContainer()
scenario.recreate()
}

FragmentFactory

讲到 Fragment 的重建,就联想到 Fragment 的实例化。Fragment 已经有很多种实例化方式了,后来又有了 FragmentScenario。我们希望能统一这些方法,而解决方案便是 FragmentFactory,它让我们可以注入 Fragment 的构造方法,也顺带解除了 Fragment 必须有一个无参构造方法的限制。

下面是一个简单的 FragmentFactory,它只有一个方法 —— instantiate,您只需要在这个方法中传入 Fragment 的类名,随后 super.instantiate() 方法就会使用反射调用对应 Fragment 的无参构造方法。正如我们在《Android 依赖注入指南》这场演讲中提到的,我们很乐意通过这种模式来减少使用者的重复工作。而如果您需要传入参数,则可以将参数传入 FragmentFactory 并通过构造方法注入将参数传入 Fragment。

接下来,您需要将 FragmentManager 的 FragmentFactory 设置为您的 FragmentFactory 。这一步最好放在 super.onCreate() 之前,因为它是重新实例化 Fragment 的地方。

private class MyFactory() : FragmentFactory() {
override fun instantiate(
classLoader: ClassLoader,
className: String
) = when (className) {
MyFragment::class.java.name -> MyFragment()
else -> super.instantiate(classLoader, className)
}
}

override fun onCreate(savedInstanceState: Bundle?) {
supportFragmentManager.fragmentFactory = MyFactory()
super.onCreate(savedInstanceState)
}

为了保证 API 的一致性,我们还准备通过下面的方式统一其他地方创建 Fragment 的方式。比如 Commit 操作,我们代理了您的 FragmentFactory,现在您只需要使用 Fragment 的类名,通过一行简单的代码,便能完成 Fragment 的创建、添加和初始化。

// 通过类名来添加 Fragment
supportFragmentManager.commit {
add(R.id.container)
}

类似的,使用 FragmentScenario 时,只需要传入您的 FragmentFactory 即可。这个 FragmentFactory 既可以是只用来模拟依赖的虚拟 Factory,也可以是用于更多测试的真实 FragmentFactory。

// 使用自定义 FragmentFactory 创建 FragmentScenario
val scenario =
launchFragmentInContainer(factory = MockFactory())

FragmentContainerView

关于 API 的一致性,我们也尝试解决了 Fragment 的另一个一致性问题。

我们发现在添加 Fragment 时,通过 标签添加与通过 FragmentTransaction 使用的是完全不同的两套系统。为了提供行为一致的 API,我们创建了 FragmentContainerView,并把它作为 Fragment 专属的容器。

FragmentContainerView 继承于 FrameLayout,但它只允许填充 FragmentView。它同时也替代了 标签,只要在 class 属性中传入类名即可。由于 FragmentContainerView 内部使用的是 FragmentTransaction,所以无需担心,稍后在替换这个 Fragment 时也不会出现问题。

<androidx.fragment.app.FragmentContainerView
class=“com.example.MyFragment”
android:id=“@+id/container”
android:layout_width=“match_parent”
android:layout_height=“match_parent” />

FragmentContainerView 也让我们有机会解决一些动画问题。例如 Fragment 在 Z 轴的层级问题。如下图所示,我们可以看到在 FrameLayout 中,Fragment 切换时没有显示动画,而是整个跳出到了屏幕上。这种问题是由于切入的 Fragment 和它的动画位于之前的 Fragment 的层级之下导致的。而 FragmentContainerView 会确保 Fragment 间的层级关系处于正确的状态,我们就可以看到切换动画了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

OnBackPressedDispatcher

另一个长期困扰我们的问题,是在 Fragment 中处理系统回退事件。为了解决这个问题,我们加入了 onBackPressedDispatcher。我们没有选择在 Fragment 中添加这个 API,而是将其加入了 Activity 中。现在任何组件都可以通过依赖 Activity 来处理回退事件。

下面是一段使用 onBackPressedDispatcher 的示例代码。您可以看到,首先 Fragment 从调用它的 Activity 中获取 onBackPressedDispatcher 对象,然后通过 addCallBack() 方法创建了一个 OnBackPressCallback,由于 Fragment 是 LifecycleOwner,所以这里可以传入 “this”。在此示例中,如果用户触发了回退操作,就会弹出一个确认窗口,而如果用户随后表示无论如何都想要退出的话,您可以先使回调失效,然后就可以执行默认的回退操作。

val dispatcher by lazy { requireActivity().onBackPressedDispatcher }
lateinit var callback: OnBackPressedCallback

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
callback = dispatcher.addCallback(this) {
showConfirmDialog()
}
}

private fun onConfirm() {
callback.enabled = false
dispatcher.onBackPressed()
}

所以这里其实并没有新的 API,只是整合了 Fragment 和架构组件现有功能。而我们接下来也打算进一步加深与架构组件的整合。举个例子,在 Fragment 中理应可以方便地获得 ViewModel 实例,但现实的状况却稍微有些麻烦。为了解决这个问题,我们创建了一些 Kotlin 属性代理。如下面的代码所示,利用这些属性代理,您可以轻松获得不同作用域的 ViewModel。

// 让获取 ViewModel 实例变得简单
val viewModel : MyViewModel by viewModels()
val navGraphViewModel: MyViewModel by navGraphViewModels(R.id.main)
val activityViewModel: MyViewModel by activityViewModels()

我们也从 Lifecycle 组件中受益良多。比如,我们不再使用自定义的生命周期方法 setUserVisibleHint,取而代之的是在添加 Fragment 到 ViewPager 或 Adapter 时调用统一的生命周期。这便是 ViewPager2 目前的工作机制,只有当前页面的 Fragment 会调用 onResume 方法。

// 设置只让当前展示的 Fragment 调用 onResume() 方法
class MyAdapter : FragmentPagerAdapter(BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

Fragment 的未来

前面讲过的功能大多在 Fragment 1.1 中已经提供,与此同时,我们强烈建议使用 FragmentContainerView 容器来存储动态添加的 Fragment,而不要使用 FrameLayout 或其他布局。

当然,未来我们还将对 Fragment 做出许许多多的改进,下面我就来介绍几个我们当前正在进行的长期规划。不过要注意的是,接下来部分内容目前还没有正式推出,所以一些细节可能会有改变。

多重回退栈 (Multiple Back Stack)

首先要讲的是多重回退栈 (Multiple Back Stack)。我们知道在 Android 中,总是会有一个 Activity 栈,而 Fragment 也实现了同样的结构,用于保存回退栈信息。而我们想要实现的则是一种同时支持单一回退栈和多重回退栈的模型,好让屏幕上不可见的 Fragment 也能保存自己的状态,从而避免状态的丢失。与此相关的使用场景,比较典型的就是底部导航一类的导航视图。

下面是一个我们的示例应用。我们想要做的事情就是让应用中每个底部标签页都拥有自己的栈,这样它们就能保存各自的状态。而当您在这些标签页间切换时,我们也将帮您处理好从一个栈到另一个栈时状态的保存和恢复。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

面试复习笔记:

这份资料我从春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

《960页Android开发笔记》

《1307页Android开发面试宝典》

包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

再深入研究,那么很难做到真正的技术提升。**

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值