Fragments作为静态内部类与独立公共类背后的设计逻辑是什么?

2022-09-01 14:37:04

我无法理解我刚刚开始的Android软件设计的一个重要方面,从我所知道的设计已被采用以分离代码,其中直觉是,保持原样并且可以在其他地方重用,甚至可能在不同的活动中,或者可能与其他片段一起, 在类似于大纲/细节流或横向 UI 的内容中。FragmentActivityFragment

好吧,所以我在SO上看到了相当多的问题,询问为什么在a中作为静态内部类放置,答案是,如果我们不使它们保持静态,则可能会包含对活动的引用,并且诸如屏幕旋转或重新绘制之类的东西可能会泄漏活动或其他内容。FragmentsActivityFragment

这让我回到了原点,我有一个问题,好吧,如果为了解耦代码而采用了Fragment设计,那么为什么我们要通过将它放在活动类而不是将它们作为独立的公共类来将它与它结合起来呢?这难道不是完全与碎片的存在相矛盾吗?FragmentActivity

拥有这样的项目结构的缺点是什么?其中每个都是自己的独立类?鉴于我的Fraction代码可以增长到1000行,特别是在尝试制作动画时,我认为这在活动中更加整洁,解耦和可重用,而不是预期的父活动。Fragment

  • 我们是否仍然遭受上述内存泄漏问题的困扰?
  • 我是否遗漏了有关设计逻辑的某些内容?请教育我。
  • 有没有办法让碎片作为一个内部类保留下来,并在其他地方使用?我可能也错过了一些东西...所以请通知我。

Project structure

任何其他项目设计方法,概念,对我的直觉的纠正都非常欢迎,因为我刚刚开始在这里,我很想知道我的所有选择。

谢谢:)


答案 1

这让我回到了原点,我有一个问题,好吧,如果为了解耦代码而采用了Fragment设计,那么为什么我们要通过将Fragment与Active结合起来,将其放在活动类中,而不是将它们作为独立的公共类?这难道不是完全与碎片的存在相矛盾吗?

片段的主要驱动因素不是解耦,而是组合:可重用的用户界面片段,可以在不同的配置中轻松组合在一起。从可组合性到模块化,从它解耦,所以是的,解耦是存在的,但这不是主要关注点。

继续阅读有关片段设计理念的信息

模块化硬币还有另一面:如果两个东西属于一起,例如一个活动和一个仅与该活动一起使用的片段,那么它们最好保持在一起,而不是分散在代码库中,这样它们就更容易一起进化。像你的问题中的项目结构,其中活动和片段位于单独的包中,不会真正遵循这个原则。

一种常见的方法是将片段保存在单独的类中,但与相关活动接近,例如使用命名前缀,以便它们在同一包内的字母顺序列表中一起排序:例如FooActivity与FooDetailsFragment。

对于代码不多且片段仅用于一个活动的简单片段,最好将它们作为该活动中的静态内部类。

只需尝试保持一致,以便阅读代码的其他人可以在代码库中轻松找到自己的方式,并且WTF /分钟代码指标保持较低。

我们是否仍然遭受上述内存泄漏问题的困扰?

否,泄漏仅适用于保存对外部类的引用的非静态内部类。包级类没有任何外部类来保存对它的引用。

由于片段共享托管活动的生命周期,因此泄漏外部对象并不是片段的真正问题。只是框架需要能够在没有任何外部类对象的情况下实例化片段,这是一个要求。static

有没有办法让碎片作为一个内部类保留下来,并在其他地方使用?我可能也错过了一些东西...所以请通知我。

您可以在代码中引用带有点表示法或反射(例如.XML文件的公共内部类)。Outer.InnerOuter$Inner

虽然这在技术上是可行的,但这样做表明你依赖于类的内部结构,这是一种设计气味。我真的会在外部类代码本身中引用内部类。


答案 2

我想知道与你的想法相反的逻辑;我一直在他们自己的课堂上制作Fragments,我的应用程序在重新定向期间像岩石一样运行。我确实使用接口与管理活动进行通信,使用适配器来管理片段,并执行基本记帐以确保我不会从重新加载中启动多个后台线程。

所以我检查 http://developer.android.com/guide/components/fragments.html 这总是值得重读的,并且知道,底部的例子正是你的建议,我每天都在使用:独立类中的两个公共片段,它们附加到一个活动上。

如果有人真的在暗示你说的话,我怀疑他们正在采取“片段必须始终嵌入到活动中,片段的生命周期直接受到主机活动的生命周期的影响”的方式,太字面意思了;它们意味着嵌入在运行时中。

咕噜咕噜!