如何构建一个优秀的App

Android简介

  • 2008年9月,谷歌正式发布了Android 1.0系统,这也是Android系统最早的版本。随后,第一部Android智能手机发布于2008年10月(HTC G1)。其实Android最早可以追溯到2003年。1.0版本还是比较简陋的,只是一个测试版。
  • 2009年4月,谷歌正式推出了Android 1.5。这个版本极大的完善了1.0版本。
  • 2009年9月,谷歌发布了Android 1.6的正式版,当年搭载这款系统的是HTC Hero(G3)。这款系统就已经非常完善了。这个版本到4.0出来时都还有用户在使用。有一段时间的开发需要同时适配1.6和2.x。
  • 2011年第一季度,Android在全球的市场份额首次超过塞班系统,跃居全球第一。也是从此时开始,大量的企业开始重视起Android App的开发。这个时期还属于架构的早期阶段,大多数人还是没有架构的概念的。Android App开发此时也还处于一个早期的探索阶段,没有任何成熟的框架或者库供开发者使用。所以可以说这个时期还属于架构的萌芽期。早期App功能都比较简单,交互也不像现在这么复杂。所以当时但是随着项目的规模增大和业务的复杂度的增长,App开发技术也随之快速发展。
  • Android 2.0/2.0.1/2.1 Eclair(松饼)2009.10.26
  • Android 2.2/2.2.1 Froyo(冻酸奶)2010.5.20
  • Android 2.3 Gingerbread(姜饼)2010.12.7
  • Android 3.0 Honeycomb(蜂巢)2011.2.2
  • Android 3.1 Honeycomb(蜂巢) 2011.5.11 
  • Android 3.2 Honeycomb(蜂巢)2011.7.13
  • Android 4.0 Ice Cream Sandwich(冰激凌三明治)2011.10.19 
  • Android 4.1 Jelly Bean(果冻豆)2012.6.28
  • Android 4.2 Jelly Bean(果冻豆)2012.10.30
  • Android 4.3 Jelly Bean(果冻豆)2013.7.25
  • Android 4.4 KitKat(奇巧巧克力)2013.11.01
  • Android 5.0 Lollipop (棒棒糖) 2014.10.16(Material Design)
  • Android 6.0 Marshmallow(棉花糖)
    AndroidHistory
    AndroidHistory
    Android在正式发行之前,最开始拥有两个内部测试版本,并且以著名的机器人名称来对其进行命名,它们分别是:阿童木(AndroidBeta),发条机器人(Android 1.0)。后来由于涉及到版权问题,谷歌将其命名规则变更为用甜点作为它们系统版本的代号的命名方法。甜点命名法开始于Android 1.5发布的时候。作为每个版本代表的甜点的尺寸越变越大,然后按照26个字母数序:纸杯蛋糕(Android 1.5),甜甜圈(Android 1.6),松饼(Android 2.0/2.1),冻酸奶(Android 2.2),姜饼(Android 2.3),蜂巢(Android 3.0),冰激凌三明治(Android 4.0),果冻豆(Jelly Bean,Android4.1和Android 4.2)。

各版本UI对比

AndroidUI
AndroidUI
Android5UI
Android5UI

Android开发工具

说到Android App开发,就不得不提一下Android的开发工具。大概是谷歌把精力都投入到了Android系统版本的更新上。在Android发布后的相当长一段时间以来,Android都没有属于自己的专用开发工具。而几乎所有的开发者都是使用eclipse+adt插件的方式进行开发—–这也是在Android Studio出现之前谷歌所提供的方式。ADT版本迭代几乎都是跟随sdk版本一起迭代的,也就是说一个版本有bug,那你至少需要等待几个月才能获得修复。ADT的功能几乎只有用来进行android apk的编译,UI可视化开发功能几乎只是用来预览。长时间没有官方专用开发工具的后果就是,虽然现在官方极力推广Android Studio,但是以前养成的习惯都短时间难以改变过来。

Android Studio
  • 2013年5月16日,在I/O大会上,谷歌推出新的Android开发环境——Android Studio,标志着Android终于有了专属的开发工具。
  • 2013年5月发布早期预览版本,版本号为0.1。2014年6月发布0.8版本,至此进入beta阶段。第一个稳定版本1.0于2014年12月8日发布
  • 2015年5月1号发布1.2版本,我从0.8版本开始尝试的AS,但是直到1.2版本开始才正式使用AS作为主要开发环境。随后的小版本迭代非常快。
  • 2016年4月8号发布了2.0正式版,全新的模拟器以及Instant run

目前最新的稳定版是2.1.2。Android Studio现在已经进入了快速迭代模式,几乎一到两周就会有一个开发版发布,大版本增加功能,小版本修复bug,多种选择。即将到来的2.2版本将会带来全新的UI开发功能。目前已经是时候全面转向Android studio了。 As有个重要的缺陷就是内存占用问题,流畅的运行最好是8G以上内存,4G内存每次编译都会造成几分钟卡顿。

Android App架构的演变

  • 早期架构
  • MVC
  • MVP
  • MVVM
  • clean

早期开发模式

Android开发最初没有丰富的第三方库使用,并且谷歌官方也没有可供参考的开发指导规范。也就是说早期的Android APP开发没有官方统一标准。 早期大多数代码都只有两个层次结构,视图层和数据层。代码中几乎都是AsyncTask 或者Thread + Handler配合使用,简单直接。 线程使用,讲究点的会用线程池进行管理,随便点的就是需要使用线程的地方就世界new Thread()。早期的代码很常见。 Activity掌管一切,非常臃肿,难以维护。 回调几乎都是通过Handler Callback实现,当回调嵌套回调的层次过多后,代码将难以跟踪和修改。

早期常用架构图:

早期架构图
早期架构图
早期架构图2
早期架构图2

MVC模式

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。 MVC架构大家都很熟悉了,尤其是j2ee开发的,每天都要面对。 随着项目的规模越来越大,业务逻辑越来越复杂。早期架构已经明显不能满足开发需求,所以人们开始寻求新的架构模式,这个时候已经非常成熟的MVC框架就自然而然的被利用起来了。 MVC的运用能减少模块之间代码的相互影响,便于添加需求和维护代码。 但是,因为Android的设计特性,Activity在MVC中既充当了C,又有一部分V,没有做到完全的解耦。所以当Ui逻辑复杂后,Activity的臃肿问题还是无法解决,大量V和C交杂在一起,解耦优势也会失去。 在android开发中,MVC架构的代码难以复用。 MVC代码比较容易理解。

MV
MV


简单的MVC实例

我们看一个最简单的MVC实例

Activity是控制器,Activity读取V视图层的数据(eg.读取当前EditText控件的数据),控制用户输入(eg.EditText控件数据的输入),并向Model发送数据请求(eg.发起网络请求等)。

mv
mv

业务逻辑处理,比如数据库存取操作,网络操作,复杂的算法,耗时的任务等都在model层处理。

mv
mv

回调,用于连接model与view

mv
mv


新MVC

当意识到Activity职责过重后,MVC便发生了进化,出现了很多新的变种框架,比如MVP,MVCP等等。可以统称为“MVX”。 “X”的引入都是为了解决M和V的同步问题。 因为变种太多,而且根据业务的不同以及每个人都有不同的特色,我们只来分析标准的架构模型。

MVP架构

什么是MVP架构?

MVP,全称 Model-View-Presenter MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。 MVP可分为PV(Passive View)和SoC(Supervising Controller)两种模式。 PV(Passive View)是一个被动的View,针对包含其中的UI元素(比如控件)的操作不是由View自身来操作,而交给Presenter来操控。 在SoC(Supervising Controller)模式下,为了降低Presenter的复杂度,将诸如数据绑定和格式化这样简单的UI处理逻辑逻辑转移到View中,这些处理逻辑会体现在View实现的接口中。

为什么要使用MVP架构?
  • 大部分的安卓应用只使用View-Model结构。当你在应用中只使用Model-View时,到最后,你会发现“所有的事物都被连接到一起”。也就是业务逻辑和数据以及视图都紧密耦合在一起,任何改动和新增功能都会引起连锁反应。并且难以跟踪bug。
  • 使用MVP就是为了把复杂的任务拆分成细小的任务。每个小任务都在规定的位置,出现bug可以很直接找到对应的代码逻辑块。
  • 完整的分离了C和V,使Activity/Fragment只保留了V的职责。把逻辑都抽象出接口,层次分明
  • 通过接口建立联系,与具体逻辑无关,可以方便的进行单元测试。
  • Presenter可以一定条件下复用
MVP架构简述
  • MVP是对MVC的改进,让Model和View完全解耦
  • MVP模式主要通过接口进行交互
  • MVP大概是2014年左右开始被人们所知道,但是直到现在还没成为Android开发标配,主要是因为推广传播的问题。
  • View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity)
  • Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合)
  • Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑
MVP架构图

mvp1
mvp1
mvp2
mvp2

MVP的缺点
  • 没有完美的架构,MVP也不例外
  • 当C被从Activity/Fragment抽离出来后,大量的工作就被转移到Presenter了。 Presenter承担了变得笨重的风险,代码的维护基本都是对Presenter的维护。
  • Presenter成为了M和V的交互纽带。如果Presenter承载了过多的视图交互,则会导致P与V的联系过于紧密。一旦视图改版,P也要跟随变更整套逻辑,相当于重写一套P。
  • 额外的代码复杂度及学习成本。MVP的架构需要拆分代码逻辑,就需要引入大量的接口和实现类,代码量会变大。并且MVP有一定的学习成本。
MVP改造实战
因涉及到具体项目代码,略过。

MVC与MVP的区别

我们直接看网上的对比图:

mvcmvp1
mvcmvp1
mvcmvp2
mvcmvp2

因此我们可以发现MVP的优点如下:

1、模型与视图完全分离,我们可以修改视图而不影响模型; 2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部; 3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。

具体到Android App中,一般可以将App根据程序的结构进行纵向划分,根据MVP可以将App分别为模型层(M),UI层(V)和逻辑层(P)。UI层一般包括Activity,Fragment,Adapter等直接和UI相关的类,UI层的Activity在启动之后实例化相应的Presenter,App的控制权后移,由UI转移到Presenter,两者之间的通信通过BroadCast、Handler或者接口完成,只传递事件和结果。 举个简单的例子,UI层通知逻辑层(Presenter)用户点击了一个Button,逻辑层(Presenter)自己决定应该用什么行为进行响应,该找哪个模型(Model)去做这件事,最后逻辑层(Presenter)将完成的结果更新到UI层。

MVVM架构

  • MVVM模式最早是微软公司提出,并且了大量使用在.NET的WPF和Sliverlight中。2005年微软工程师John Gossman在自己的博客上首次公布了MVVM模式。
  • MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。Angular 和 Ember 都采用这种模式。
  • 现在MVVM风头正劲,不过还没有十分红火,原因是Data-binding还没有完美实现,Android前段时间才支持数据的双向绑定。
  • Anroid MVVM需要Android Studio的支持,目前Data-binding最新版本才1.1,还有很多未知的坑,所以不建议在正式项目中使用。
MVP与MVVM对比

mvpmvv
mvpmvv


Clean Architecture

cleanarch
cleanarch


Flux

flux
flux

主要架构总结

zongjie
zongjie

谢谢大家!