Android上的MVC模式

有可能在Java中为Android实现模型-视图-控制器模式吗?

或者它已经通过活动实现了吗?或者有没有更好的方法来实现Android的MVC模式?

255142 次浏览

Android上的动作、视图和活动是与Android UI一起工作的内置方式,是模型-视图-视图模型(MVVM)模式的实现,它在结构上与模型-视图-控制器相似(在同一家族中)。

据我所知,没有办法打破这个模式。这可能是可以做到的,但是您可能会失去现有模型的所有好处,并且必须重写自己的UI层以使其正常工作。

没有一个单一的MVC模式可以遵循。MVC只是或多或少地说明了你不应该将数据和视图混为一谈,例如,视图负责保存数据,或者处理数据的类直接影响视图。

但无论如何,Android处理类和资源的方式,有时你甚至被迫遵循MVC模式。在我看来,更复杂的是那些有时负责视图,但同时又充当控制器的活动。

如果您在XML文件中定义视图和布局,从res文件夹加载资源,并且如果您或多或少地避免在代码中混合这些东西,那么您无论如何都是在遵循MVC模式。

在Android中,你没有MVC,但你有以下:

  • 你可以根据分辨率、硬件等在各种XML文件中定义用户界面
  • 你可以在不同的XML文件中根据语言环境等定义你的资源
  • 你可以扩展像ListActivityTabActivity这样的类,并通过增压泵来使用XML文件。
  • 您可以为业务逻辑创建任意数量的类。
  • 很多跑龙套已经为你写了- DatabaseUtils, Html。

使用布局、资源、活动和意图创建Android UI是MVC模式的实现。请参阅下面的链接,以了解更多关于此- http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

镜像为pdf

没有普遍唯一的MVC模式。MVC是一个概念,而不是一个可靠的编程框架。你可以在任何平台上实现你自己的MVC。只要你坚持以下基本思想,你就是在实现MVC:

  • 模型:渲染什么
  • 如何渲染
  • 控制器:事件,用户输入
也可以这样考虑:当你为模型编程时,模型不应该担心呈现(或特定于平台的代码)。模型会对视图说,我不在乎你的渲染是Android, iOS还是Windows Phone,这是我需要你渲染的。 视图将只处理特定于平台的呈现代码

当你为了开发跨平台应用程序而使用莫诺来共享模型时,这一点特别有用。

我同意JDPeckham的观点,并且我相信XML本身不足以实现应用程序的UI部分。

然而,如果你认为Activity是视图的一部分,那么实现MVC是相当简单的。你可以重写应用程序(由Activity中的getApplication()返回),在这里你可以创建一个在应用程序的生命周期中存在的控制器。

(或者,您也可以使用应用程序文档中建议的单例模式)

Android的MVC模式(有点)是用它们的适配器类实现的。他们用“适配器”替换控制器。适配器的描述声明:

Adapter对象充当AdapterView和

.视图的底层数据

我只是在寻找一个从数据库读取的Android应用程序,所以我不知道它工作得有多好。然而,它看起来有点像Qt的模型-视图-委托架构,他们声称这是传统MVC模式的一个升级。至少在PC上,Qt的模式运行得相当不错。

我发现在Android上实现MVC的最佳资源是这篇文章:

我在自己的一个项目中采用了同样的设计,效果非常好。我是Android的初学者,所以我不能说这是最好的解决方案。

我做了一个修改:我实例化了应用程序类中每个活动的模型和控制器,这样当横向-纵向模式更改时就不会重新创建这些模型和控制器。

我认为最有用的简化解释是: http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf < / p >

从我在这里看到和读到的所有东西来看,实现所有这些东西都变得更加困难,并且与android的其他部分不太适应。

让一个活动实现其他监听器已经是标准的Android方式。最无害的方法是像幻灯片所描述的那样添加Java观察者,并将onClick和其他类型的操作分组到仍然在Activity中的函数中。

Android的方式是Activity两者都做。与之斗争并不能真正使扩展或将来的编码变得更容易。

我同意第二篇文章。它已经实现了,只是不是人们习惯的方式。不管它是否在同一个文件中,已经有分离了。不需要创建额外的分隔来适应其他语言和操作系统。

经过一番搜索,最合理的答案是:

MVC已经在Android中实现了:

  1. View = layout,资源和内置类,如Button,派生自android.view.View
  2. 控制器=活动
  3. 模型=实现应用程序逻辑的类

(顺便说一下,这意味着活动中没有应用程序域逻辑。)

对于小型开发人员来说,最合理的做法是遵循这种模式,不要尝试做谷歌决定不做的事情。

PS注意,Activity有时会重新启动,所以它不是模型数据的地方(引起重新启动的最简单的方法是从XML中省略android:configChanges="keyboardHidden|orientation"并转动您的设备)。

编辑

我们可能正在谈论MVC,但它将是这样说FMVC模型-视图-控制器框架框架 (Android操作系统)强加了它的组件生命周期和相关事件的想法,而在实践中,控制器 (Activity/Service/BroadcastReceiver)首先负责处理这些框架强加的事件(例如onCreate ())。是否应该单独处理用户输入?即使应该,你也不能把它分开,用户输入事件也来自Android。

无论如何,在Activity/Service/BroadcastReceiver中插入的非android专用代码越少越好。

虽然这篇文章看起来很旧,但我想添加以下两篇文章来介绍Android在这一领域的最新发展:

android-binding -提供一个框架,使android视图小部件绑定到数据模型。它有助于在android应用程序中实现MVC或MVVM模式。

roboguice - RoboGuice把猜测工作的开发。注入您的视图,资源,系统服务,或任何其他对象,并让RoboGuice照顾的细节。

我看到很多人说MVC已经在Android中实现了,但这不是真的。Android默认不遵循MVC。

因为我不谷歌将永远强制MVC实现像iPhone的限制,但它取决于开发人员的模式或技术,他们想在他们的项目,在小或简单的应用程序使用MVC是不需要的,但随着应用程序的增长,变得复杂,并需要修改其代码在以后的几年,然后有一个MVC模式在Android的需求。

它提供了一种简单的方法来修改代码,也有助于减少问题。 如果你想在Android上实现MVC,那么按照下面给出的链接,在你的项目中享受MVC实现

http://www.therealjoshua.com/2011/11/android-architecture-part-1-intro/

但是现在,我认为MVP和Android架构模式是开发人员应该使用的干净和健壮的Android应用程序的最佳选择之一。

当我们将MVC、MVVM演示模型应用于Android应用程序时,我们真正想要的是有一个清晰的结构化项目,更重要的是更容易进行单元测试。

目前,如果没有第三方框架,通常会有大量代码(如addXXListener()、findViewById()等),这不会增加任何业务价值。

更重要的是,你必须运行Android单元测试,而不是正常的JUnit测试,后者需要很长时间才能运行,并且使单元测试有些不切实际。由于这些原因,几年前我们开始了一个开源项目,RoboBinding -一个用于Android平台的数据绑定表示模型框架。

RoboBinding帮助您编写更易于阅读、测试和维护的UI代码。RoboBinding消除了对不必要的代码,如addXXListener等的需求,并将UI逻辑转移到表示模型,这是一个POJO,可以通过正常JUnit检验进行测试。RoboBinding本身带有300多个JUnit测试,以确保其质量。

根据Xamarin团队解释的的解释(在iOS MVC上“我知道这看起来很奇怪,但等一下”):

  • 模型(数据或应用程序逻辑),
  • 视图(用户界面)和
  • 控制器(后面的代码)。

我可以这样说:

Android上的模型只是一个可打包对象。视图是XML布局,控制器是(活动+它的片段)。

*这只是我个人的观点,不是来自任何资源或书籍。

模型视图控制器(MVC) .

enter image description here


描述:

    当我们必须在软件开发中主要进行大型项目时,MVC 通常使用,因为它是一种通用的组织方式 李项目。< / >
  • 新的开发人员可以很快适应项目
  • 帮助开发大型项目和跨平台。

MVC模式本质上是这样的:

  • 模型:显示什么。这可以是数据源(例如:服务器,原始 应用程序中的数据)
  • 视图:显示方式。这可以是xml。因此,它是作为一个 表示过滤器。视图附加到它的模型(或模型部分) 并获取表示所需的数据
  • 控制器:处理类似用户输入的事件。这就是活动

MVC的重要特性: 我们可以修改模型或视图或控制器,但不影响其他的

    比如我们改变视图的颜色,视图的大小或位置 风景。这样做不会影响模型或控制器
  • 假设我们改变模型(而不是从服务器获取的数据 从资产中获取数据)仍然不会影响视图和 李控制器< / > 假设我们改变了控制器(活动中的逻辑),它不会影响 模型和视图

厌倦了MVx在Android上的灾难,我最近做了一个小库,提供单向数据流,类似于MVC的概念:https://github.com/zserge/anvil

基本上,您有一个组件(活动、片段和视图组)。在内部定义视图层的结构和样式。此外,您还可以定义数据应该如何绑定到视图。最后,您可以在同一位置绑定侦听器。

然后,一旦你的数据被改变——全局的“render()”方法将被调用,你的视图将会被最新的数据巧妙地更新。

下面是一个组件的例子,为了代码紧凑,组件中包含了所有内容(当然,模型和控制器可以很容易地分开)。这里“count”是一个模型,view()方法是一个视图,“v -> count++”是一个控制器,它监听按钮点击并更新模型。

public MyView extends RenderableView {
public MyView(Context c) {
super(c);
}


private int count = 0;


public void view() {
frameLayout(() -> {              // Define your view hierarchy
size(FILL, WRAP);
button(() -> {
textColor(Color.RED);      // Define view style
text("Clicked " + count);  // Bind data
onClick(v -> count++);     // Bind listeners
});
});
}

使用分离的模型和控制器,它看起来像:

button(() -> {
textColor(Color.RED);
text("Clicked " + mModel.getClickCount());
onClick(mController::onButtonClicked);
});

在这里,点击每个按钮的数量都会增加,然后“render()”将被调用,按钮文本将被更新。

如果使用Kotlin: http://zserge.com/blog/anvil-kotlin.html,语法将变得更加舒适。此外,对于没有lambdas的Java还有其他语法。

这个库本身是非常轻量级的,没有依赖关系,不使用反射等等。

(声明:我是这个库的作者)

你可以在Android中实现MVC,但它不是“原生支持”的,需要一些努力。

也就是说,我个人倾向于最有价值球员作为一个更干净的Android开发架构模式。说到MVP,我的意思是:

enter image description here

我还发布了一个更详细的答案在这里

在体验了Android中MVC/MVP实现的各种方法后,我提出了一个合理的架构模式,我在这篇文章中描述了它:Android中的MVP和MVC架构模式

MVC- Android架构 在android中最好遵循任何MVP而不是MVC。但仍然根据问题的答案,这可以是解

Enter image description here

描述及指引

     Controller -
Activity can play the role.
Use an application class to write the
global methods and define, and avoid
static variables in the controller label
Model -
Entity like - user, Product, and Customer class.
View -
XML layout files.
ViewModel -
Class with like CartItem and owner
models with multiple class properties
Service -
DataService- All the tables which have logic
to get the data to bind the models - UserTable,
CustomerTable
NetworkService - Service logic binds the
logic with network call - Login Service
Helpers -
StringHelper, ValidationHelper static
methods for helping format and validation code.
SharedView - fragmets or shared views from the code
can be separated here


AppConstant -
Use the Values folder XML files
for constant app level

注1:

这是你可以施展的魔法。在对代码段进行分类之后,编写一个基本接口类,比如IEntity和IService。声明通用方法。现在创建抽象类BaseService,声明您自己的方法集,并分离代码。

注2:如果你的activity呈现了多个模型,那么与其在activity中编写代码/逻辑,不如将视图划分为片段。那就好多了。因此,如果将来需要在视图中显示更多的模型,请再添加一个片段。

代码分离是非常重要的。体系结构中的每个组件都应该是独立的,而不是相互依赖的逻辑。如果碰巧你有一些相关的逻辑,那么在两者之间写一个映射逻辑类。这对你将来会有帮助。

没有实现的MVC体系结构,但是存在一组库/示例来实现MVP(模型-视图-呈现器)体系结构。

请查看这些链接:

谷歌增加了一个Android架构MVP的例子:

令人惊讶的是,这里没有一个帖子回答这个问题。它们要么太笼统,模糊,不正确,要么没有解决在android中的实现。

在MVC中,视图层只知道如何显示用户界面(UI)。如果需要任何数据,则从模型层获取。但是视图不会直接要求模型查找数据,而是通过控制器。因此控制器调用模型来为视图提供所需的数据。一旦数据准备好,控制器通知视图数据已经准备好,可以从模型中获取。现在视图可以从模型中获取数据。

这个流程可以总结如下:

enter image description here

值得注意的是,视图可以通过控制器——也称为被动MVC——或者通过向模型注册可观察对象来观察模型中的数据,即活跃的MVC,来了解模型中数据的可用性。

在实现部分,首先想到的事情之一是,应该为视图?Activity还是Fragment ?

答案是没有关系,两者都可以使用。视图应该能够在设备上呈现用户界面(UI),并响应用户与UI的交互。ActivityFragment都为此提供了所需的方法。

这篇文章中使用的示例应用程序中,我已经为视图层使用了Activity,但Fragment也可以使用。

完整的示例应用程序可以在我的GitHub repo 在这里的“mvc”分支中找到。

我还通过一个例子在这里处理了android中MVC架构的优点和缺点。

对于那些感兴趣的人,我已经开始了一系列关于android应用程序架构在这里的文章,在其中我比较了不同的架构,即MVC, MVP, MVVM,通过一个完整的工作应用程序开发android应用程序。

在我看来,Android处理MVC模式的方式是这样的:

您有一个充当控制器的Activity。你有一个负责获取数据的类,即模型,然后你有一个View类,即视图。

当谈到视图时,大多数人只想到xml中定义的可视部分。不要忘记,视图也有一个程序部分,它的构造函数,方法等,在java类中定义。