用于数据加载的Android活动/片段职责

Vin*_*rat 37 android

在为客户启动新应用程序时,我再次问自己应该负责加载数据的相同问题:活动或片段.我已经为各种应用程序采取了两种选择,我想知道哪种模式最适合您:

  • 限制代码复杂性.
  • 处理边缘情况(如屏幕旋转,屏幕省电,连接丢失等)

选项1 - 活动加载数据和片段仅显示它

这允许具有仅被馈送一堆对象的片段来显示.他们对加载数据以及我们如何加载数据一无所知.

另一方面,活动使用任何需要的方法加载数据(例如,最初最近的50个条目和搜索,加载搜索结果).然后它将它传递给显示它的片段.加载数据的方法可以是任何东西(来自服务,来自DB,......片段只知道POJO)

它是一种MVC架构,其中活动是控制器,片段是视图.

选项2 - 活动安排片段和片段负责获取数据

在这种模式中,片段是应用程序的自主部分.他们知道如何加载他们正在显示的数据以及如何向用户显示数据.

活动只是一种在屏幕上排列片段并协调应用程序活动之间转换的方法.

My *_*God 17

理论上,如果它有效,你可以做任何你想做的事.实际上,片段和活动会显示数据并处理自己的生命周期.

由于片段属于活动,因此您必须同时使用两者来更好地处理所有数据,但这主要取决于您的需求.

如果你记住Fragment应该提供UI并且Activity应该提供处理的想法那么你就可以很好地划分关注点和代码,这样就可以重用Fragment或Activity.

如果您了解MVC - 模型视图控制器 - 设计模式,那么您可以将片段视为视图,将活动视为模型.

当您使用多个片段构建应用程序时,事情变得更加有趣.

一些关键点作为决定因素 -

  • Fragment的想法是它是一个包装好的UI块,可供任何需要它的Activity使用.在此基础上,您必须问自己,每个活动必须处理的事件是相同的还是每个活动的唯一活动.如果它是相同的,则事件处理程序最好在Fragment中编写.

  • Fragment没有自己的UI - 它由Fragment与之关联的Activity显示.事件由View层次结构中的对象生成,该对象由Activity拥有.例如,如果您尝试使用Android Studio添加事件处理程序,它会将其添加到Activity而不是Fragment.

  • 您可以EventListener在Fragment中定义要处理事件的对象,然后将其连接到要在其中生成事件的Activity中的View对象.

  • Fragment是一个实现onCreateView提供可由Activity显示的View层次结构的方法的类.

  • 要在Activity中使用Fragment,您必须使用FragmentManager和FragmentTransaction添加它.您可以使用add方法添加Fragment,但在调用commit方法之前不会发生任何事情.

  • 在使用提交的方法之后,通常是Activity的onCreate,终止CreateView事件运行Fragment的onCreateView,并将Fragments View层次结构添加到Activity的内容中.

  • 您必须编写代码来保存和恢复Fragment可能具有的任何其他状态.

  • 如果任务对Fragment的所有实例都是通用的,那么它的代码应该存在于Fragment中.

  • 特别是处理事件的代码可以在Fragment中定义.

  • 应该使用Activity来托管处理UI提供的数据的代码.

  • 将Activity事件处理程序附加到Fragment的UI或很难正确执行.

  • 从场景中决定您的应用程序将是什么.是服务,活动,小部件,甚至内容提供商还是复杂系统,包括一些不同的组件.根据场景测试您的决策.

  • 所有这些都必须在片段被销毁和重新创建后工作.

    (1)Initialization of the Fragment,(2)Saving and restoring the Fragment's state和(3)Implementing something like an event mechanism so the Fragment can get the Activity's attention

    最难的部分是实现类似事件机制的东西.

  • 在复杂系统的情况下,在应用程序组件之间分发功能和数据实体.列出组件及其内容(活动或其他).

  • 制作UI组件列表,其中包含描述它们的功能(不是现在).这些将是小部件和活动或片段或布局.

  • 通常,您会希望一个片段与另一个片段进行通信,例如根据用户事件更改内容.所有Fragment-to-Fragment通信都是通过相关的Activity完成的.两个碎片永远不应该直接通信.

  • 当您的应用程序完全模块化时,碎片不会彼此了解.您可以添加片段,删除片段,替换片段,它们都可以正常工作,因为它们都是独立的,并且活动可以完全控制配置.

  • 除非您开始交易,否则您无法对片段执行任何操作.在事务中,您可以设置要发生的事情,通常将Fragment添加到当前布局,但在使用commit方法之前没有任何反应.

使用屏幕方向高效处理数据 -

当屏幕方向改变时,Android重新启动正在运行的Activity(onDestroy()被调用,然后是onCreate()).

要正确处理重新启动,您的活动必须通过正常的活动生命周期恢复其先前的状态,在此生命周期中Android会onSaveInstanceState()在销毁活动之前调用,以便您可以保存有关应用程序状态的数据.然后,您可以在onCreate()或期间恢复状态onRestoreInstanceState().

但是,您可能会遇到这样的情况:重新启动应用程序并恢复大量数据可能成本高昂,并且会导致糟糕的用户体验.在这种情况下,您还有两个选择:

1) 在配置更改期间保留对象

允许您的活动在配置更改时重新启动,但将有状态对象带到您的活动的新实例.

2) 自己处理配置更改

在某些配置更改期间阻止系统重新启动您的活动,但在配置更改时接收回调,以便您可以根据需要手动更新活动.

我要做的是管理bluetooth, database storage, etcActivity中的所有数据流(),并仅使用Fragments显示UI或处理用户输入.

这种方式更容易处理配置更改/屏幕旋转.

此外,如果数据流在UI线程上很重要,请考虑使用Service带有后台线程的a.如果它是"一次性"的东西,你可以使用一个IntentService,否则你可以实现一个Bind Service并从你有Context的任何地方请求绑定.

更多阅读 - 片段和活动 - 一起工作.


Dmi*_*ide 14

理想的情况是既没有Activity,也不Fragment 与UI应该包含任何"模式"的逻辑-这些类应该是重量轻,只负责UI逻辑.但是,当您决定制作单独的模型对象时,您可能会选择初始化和存储此对象的位置以及如何处理配置更改.这里有一些方便的技巧:

您可以创建一个没有UI模型 ,让它保留实例来处理配置更改(它是AFAIK在配置中保存数据的最简单方法.更改没有麻烦)并在任何需要的地方检索它.你在里面做了所有昂贵的操作(当然是使用后台线程),存储你的数据就完成了.有关更多信息,请参阅添加没有UI部分的片段.Fragment findFragmentById()

UPD:现在有更好的方法来处理配置更改:来自Google架构组件的ViewModel.这是一个很好的例子.