分割还是不分割-针对活动的嵌套片段。为什么要使用多个活动?


70

关于是否应使用Activities还是使用了很多讨论Fragments。例如:

我发现的大多数讨论都是在Android 4.2之前发布的。
Google借助Android 4.2发明了嵌套片段

因此,我实际上再也看不到任何理由使用多个 Activity

在初期,Fragments它们应该在Apps中用于支持Tablets舒适地同时智能手机

因此,例如,您有一个ListView可以打开View有关单击项目的详细信息。在智能手机上,我们将替换ListView并显示详细信息View。而平板电脑,而不是与详细信息视图替换列表可以同时显示Views在同一时间。


现在有了嵌套,Fragments还有许多其他可能性。如果您要使用单个Activity,可以将常规信息存储在Activity,每个Fragment人都可以访问它。

除此之外,Fragments谁筑巢Fragments人还可以为他们的孩子存储信息Fragments

有了Fragments我可以轻松地重用的方式Views,我可以同时显示多个内容,并且可以轻松地Fragment从一个对话框中形成一个对话框。Fragment。这一切可能只需要我执行一些复制和粘贴操作。

如果我Activities改用了,我必须认真地进行很多更改以完成此操作。


我最近实现了一个应用程序,在其中我可以轻松地使用两个应用程序Fragment-ViewPager使事情变得真正美丽和动态(某种形式:今天的信息-昨天的信息)。我认为Fragments让我们的生活更轻松:)


问题:

  • 为什么要使用多个Activity

您能否提供一个很好的示例,在其中使用多次Activities而不是使用更有意义Fragments

  • 有什么好的例子,您别无选择,只能使用Activities吗?

我认为大多数较大的框架(如MapsYouTube和co)都已支持Fragments。因此,我们不必依赖Activities。也就是它很容易对付NavigationBarTabHostsViewPagerActionBar如果你使用Fragments


从Udacity:

为什么不总是创建一个带有很多片段的活动?

  1. 复杂性增加
  2. 更难的意图处理
  3. 难以阅读,维护和测试
  4. 紧密耦合的风险
  5. 安全问题

2
我从来没有想过只使用一个活动。Android体系结构建议应用程序由活动组成,而活动由片段组成,因此我坚持这一点。期待一些有趣的答案。
Gustek

1
嘿,我希望一些专家可以回答这个问题:在上周,一位客户说他希望有一个弹出窗口而不是额外的View。当我说他只需要更改两行代码时,他真的感到惊讶:)。
Frame91 2013年

5
您假设嵌套片段实现良好。我已经看到来自专家和非专家的足够多的推文和其他评论,可以将嵌套的片段放入“紧急情况下”存储桶中。
CommonsWare 2013年

2
但是,为什么我要认真使用多个活动?我从中得到什么好处?我看到一个很大的缺点:我只能同时使用一个Activity。仅使用片段会有性能问题吗?而且您也可以清楚地将Activity实施为错误的;)
Frame91 2013年

2
我的Android手册宣称该方法论为“ AUF!” ->始终使用片段!作者主要陈述了Pro的优点:片段节省了资源,并且使在应用程序开发的后期添加更改变得更加容易。
bofredo

Answers:


95

首先,我同意您的观点,即可以仅使用一个活动和嵌套片段来编写大型应用程序。这就是软件的乐趣-您可以使用多种方法来实现相同的功能。对我而言,选择使用多个活动取决于我个人对封装性,可重用性和可测试性的偏爱。

如果我有一个可在其他应用程序中重用的小部件,则将其设为片段。例如,我的应用程序具有“与服务器同步”按钮,并且我创建了一个自定义片段,该片段使用进度条以可视方式显示同步过程。容易想象另一个应用程序可以使用此小部件,因此这就是我将其开发为Fragment的原因。

如果我要在应用程序内切换任务,以使新任务在概念上与先前的任务无关,那么我将使用新的活动。例如,我的应用程序的第一页要求您选择一个用户。单击用户后,我会将您发送到该用户的主菜单。该用户的主菜单显示在新活动中。

现在,让我们想象一个大型,复杂的应用程序,并指派了一组开发人员来开发该应用程序。如果将应用程序划分为多个单独的活动,则从概念上讲,将任务划分起来非常容易。每个活动都是其自己的沙箱,因此并行开发简单且可测试。当然,如果有任何共同需求,团队仍应开发Fragments并重用它们。我应该补充说,代码重用在软件开发中不会经常发生,但是如果操作正确,应该会有很多可重用的Fragments。

现在假设是时候测试应用程序了。您的测试团队可以将每个活动视为自己的黑匣子。这比依赖单个活动和大量嵌套片段的单个大型应用程序更易于测试。如果存在错误,这尤其重要。如果存在一个不明显的错误,至少我知道该错误的范围仅限于多个活动中的一个活动。

总而言之,我的猜测是您正在单独开发应用程序,因此您的开发决策不会影响其他任何人。如果您正在与更大的团队一起开发应用程序,则您的观点可能会发生变化,并且我希望从这一角度讲,我的回答很有道理。


2
谢谢。很高兴被赞赏!
Steven

1
我给了您赏金,因为它会在tmw之前过期...但是我仍然想听听片段/活动的更多优缺点;)
2013年

1
这就是问题,片段加载比启动新活动快得多!
theblang

2
我认为,如果在测试片段时遇到麻烦,他们需要改进其测试框架或重构其代码。如我所见,该片段是用于存储数据和处理UI的内存。业务逻辑,数据库访问和API调用应位于(易于测试的)服务类中。
人类的android14年

2
对,那是正确的。如果一个片段包含业务逻辑,那么它不可能在其他上下文中重用,因此它将违背片段的预期目的。专业的开发人员应该能够区分Fragments和服务类等UI类。对于技术水平较低的开发人员而言,令人困惑的事情是了解通过创建服务类来分离逻辑的需求,而Android框架并未明确要求这些类。
2014年

2

你是对的。一个人可以单独处理很多碎片。但是,根据Activity类,活动是用户可以做的一件专注的事情。我总是倾向于将我的应用程序划分为顶级活动,此外还划分为多个片段。

例如,在这种情况下,多项活动有意义。我们的应用程序具有某些功能,如果用户登录后可以扩展。但是,用户在登录之前仍可能会使用此有限功能。说,除了登录后,您不能对项目发表评论。在这种情况下,我们的MainActivity可能会显示整个功能。如果用户要发表评论,我们要求他通过保存请求并启动活动LoginActivity来登录,该活动处理登录/注册并在完成后设置正确的结果。在调用的Fragment或Activity中,我们检查结果是否为LOGIN_SUCCESS或用户当前是否已登录并处理未决请求。我要说的是,登录的操作流程应该是一个单独的活动。否则,处理可能会混乱。通过这种方式,任何需要登录的操作都可以调用startActivityForResult(LOGIN)并将其自身保存为未决操作。然后,在设置结果之后,我们可以在super.onActivityResult中实现处理。当然,所有这些都是理论上的,一个人可以零碎地实现Login。但是,代码肯定会被融合。

您需要活动的另一种情况是您的活动提供了导出的服务。例如,假设您是“文件上传器”的开发人员,并且收到了上传文件的意图。在这种情况下,创建一个可以使用上载文件请求的活动非常方便。

然而,在当前更新中,Fragments的功能涵盖了android应用程序的大多数功能,因此可以与单个主机活动一起单独使用,以满足应用程序的要求。

但是,整个带有数据的“单个活动主机”的防御能力很弱。活动和紧密的片段具有整个生命周期,包括通过捆绑包保存/恢复实例。单个主机活动可能会持续很长时间,并且托管多个片段,这些片段可能在其活动的单个生命周期中被多次回收。因此,很可能某个活动随时间推移持有所有这些实例而超出其资源预算。当数据确实在多个对象之间共享时,开发人员有责任将数据保留在共享上下文中。这是该方法的缺点。在我们的示例中,MainActivity消耗额外的数据字节是没有意义的,因为它可以在可能需要睡眠的情况下托管Login片段,并在需要时释放其内存。

最后,一个好的程序员可以设法完成同样的任务。


记录的好例子!但是,如果我们为此使用片段,则可以轻松地为登录实现FragmentDialog,以便用户不必切换活动,而可以停留在需要进一步权限的站点上。在我看来,这将提供更好的工作流程,即使就像您说的那样可能会导致代码完全混乱(也可以在不弄乱代码的情况下处理这种情况。例如,让所有片段都从接口“ UserPermissionInterface”实现”之类的方法,例如我们可以从活动中退出的登录或注销之类的方法
Frame91

我很好奇,您实现了导航抽屉吗?如果是这样,您如何在多个活动中处理它,而不编写一堆重复的代码?
theblang 2014年

@mattblang实际上,我从未实现带有活动的导航抽屉:我觉得很奇怪。我明白你的意思了。
Sherif elKhatib 2014年

我已经通过使用所有需要共享的活动的基类,简单地使用Activity实现了一个一致的导航抽屉。我不记得遇到严重的问题。
Nestor Ledon 2015年

2

你是完全正确的!

为什么要使用多个活动?

您能否提供一个很好的示例,其中使用多个Activity而不是使用Fragments更有意义?

有没有什么好例子,您除了使用活动之外别无选择?

我认为大多数较大的框架(如Maps,YouTube和co)都已支持Fragments。因此,我们不必依赖活动。如果使用Fragments,也很容易处理NavigationBar,TabHosts,ViewPager,ActionBar。

始终使用Fragments不利于将数据扩展到UI,尤其是在以下情况下

  • ConnectionTimeOut(或互联网速度较慢),因为初始化数据花费了很多时间。因此,有时使用每个活动来填充少量数据要比每个片段要好。

  • 或者对于使用方法onActivityResult来说更灵活,使用活动性也要好于。例如 您可以在应用程序中调用FileDialogChooser

在某些情况下,

谢谢,


1

对于您的问题,我只能说有时候,对于复杂的用户体验或复杂的应用程序,必须使用不同的硬件组件,您需要使用活动而不是片段。

例如,如果您必须创建具有某种形式的应用程序,该应用程序具有拍摄照片的步骤,然后将该照片用于使用内存的某些工作硬性存储任务(例如人脸检测),则需要将此任务与主任务分开任务活动并个性化清单上的权限,以便仅对此活动使用更多内存。

另一个示例是如果您要使用弱内存活动(在清单中,您可以设置属性以清除活动堆栈,并在活动结束时强制垃圾回收器清除内存)

需要使用更多活动和片段的最可能情况是应用程序的用户体验。如果您需要一个包含菜单的右抽屉自定义,并且菜单的每个片段都包含一个listView,则每个列表视图都必须包含详细信息。您可以做很多技巧来隐藏正确的抽屉,并创建动画以从片段滑动到细节,但是最好和最简单的方法是为细节创建新活动,并使用与主界面分开的逻辑/生命周期进行管理活动与抽屉。我已经在我的两个应用中完成了此选择:

iMeal- https://play.google.com/store/apps/details? id = it.fullsix.chiccopappe

GGRugby- https://play.google.com/store/apps/details? id = it.f6.template

在此应用中,抽屉位于主片段活动中,每个菜单都会更改内容片段。内容片段中的列表视图有意地更改活动上下文,并进入另一个活动。

最后,在某些情况下,我认为您应该使用一个以上的fragmentActivity进行更多工作……但这是我的工作方式,可能您可以找到一种技巧/方式或范围来仅使用一个Activity和fragment做某事。


请阐明“最佳”的含义。这很可能是最简单的方法,但是我无法找到可以证明所链接的应用程序中这种列表/详细信息分离合理性的东西(例如您所讨论的内存消耗)。
Giulio Piancastelli,

我列出的应用程序是针对User Expreience的情况。占用大量内存的应用程序不在商店中,而是安装在用于创建一些我无法在此处发布的PhotoBox的临时硬件上。只是我认为这有一定范围的应用程序必须有一些活动可以在清单的所有属性进行个性化,你可以在这里找到:developer.android.com/guide/topics/manifest/...
phemt.latd

0

我知道我为时已晚,但Square对片段有意见。这是本文的要旨:

片段:经验教训

尽管它们有缺点,但片段却教会了我们宝贵的经验,现在我们可以在编写应用程序时重新应用它们:

  • 单一活动界面:无需为每个屏幕使用一个活动。我们可以将我们的应用程序拆分为解耦的小部件,并根据需要组装它们。这使动画制作和生命周期变得容易。我们可以将小部件分为视图代码和控制器代码。
  • Backstack不是特定于活动的概念;您可以在活动中实施后退堆栈。
  • 不需要新的API。我们需要的一切从一开始就存在:活动,视图和布局填充器。

您不必使用多个活动,也不必使用片段。您只能将自定义视图与其演示者一起使用。

您可以在这里阅读:https : //corner.squareup.com/2014/10/advocating-against-android-fragments.html

您还可以在这里找到Square的砂浆库:https//github.com/square/mortar

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.