细谈Android应用架构

   说真的,接触Android编程不多,通常用visual studio的c#,vc++,c#应用架构熟悉,Java熟悉,Python熟悉,但对Android陌生,朋友说学Android好久啦,并且已经上班,他说,Android开发生态圈的节奏很是之快。每周都会有新的工具诞生,类库的更新。我不得不学习它,其实支持Android的集成开发环境也多。 html

以Android Studio集成开发环境为例


  2013年GoogleI/O大会首次发布了Android Studio IDE(Android平台集成开发环境)。它基于Intellij IDEA开发环境,旨在取代Eclipse和ADT(Android开发者工具)为开发者提供更好的开发工具。既然Google一直在努力推广,相信不久之后就有望遇上Eclipse。 java

  • 相比Eclipse,Android Studio IDE有本身的特色:
  • 对UI界面设计和编写代码有更好地支持,能够方便地调整设备上的多种分辨率。
  • 一样支持ProGuard工具和应用签名。
  • 不过,目前版本的Android Studio不能在同一窗口中管理多个项目。每一个项目都会打开一个新窗口。我猜这是借鉴了Intellij IDEA的行为,并且Google近期不会对此作出调整。
  • 支持Gradle自动化构建工具,这真是极好的,但对于刚从Eclipse平台转移过来的开发者来讲还须要一段时间去学习和适应。

2、下载和安装相关软件

2.一、开发环境 

  物理机版本:Win 8(64位) react

  Java SDK版本:jdk-7u45-windows-x64(64位) android

  Android Studio版本:android-studio-bundle-135.1740770-windows c++

  注:物理机版本和Java SDK版本必需要保持一致,即:同为64位或者同为32位。 git

2.二、下载JDK

  我下载的是JDK1.7的版本,下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html github

  

  下载到本地电脑后双击进行安装。JDK的安装过程比较简单,安装过程基本上就是一路Next便可,作Java开发的人都会,在安装的时候只须要注意将JDK和JRE安装到同一个目录便可,JDK默认安装成功后,会在系统目录下出现两个文件夹,一个表明jdk,一个表明jre 数据库

  

  JDK的全称是Java SE Development Kit,也就是Java 开发工具箱。SE表示标准版。JDK是Java的核心,包含了Java的运行环境(Java Runtime Environment),一堆Java工具和给开发者开发应用程序时调用的Java类库。
  咱们能够打开jdk的安装目录下的Bin目录,里面有许多后缀名为exe的可执行程序,以下图所示:
  
  这些都是JDK包含的工具,经过配置JDK的变量环境,咱们能够方便地调用这些工具及它们的命令。
  JDK包含的基本工具主要有:
  • javac:Java编译器,将源代码转成字节码。
  • jar:打包工具,将相关的类文件打包成一个文件。
  • javadoc:文档生成器,从源码注释中提取文档。
  • java:运行编译后的java程序。

2.三、配置Windows上JDK的变量环境

  为了配置JDK的系统变量环境,咱们须要设置两个系统变量,分别是JAVA_HOME,Path。下面是这两个变量的设置。
  一、JAVA_HOME
    先设置这个系统变量名称,变量值为JDK在你电脑上的安装路径:E:\Program Files\Java\jdk1.7.0_75建立好后则能够利用%JAVA_HOME%做为JDK安装目录的统一引用路径。
  
  二、Path
    PATH属性已存在,可直接编辑,在原来变量后追加:;%JAVA_HOME%\bin
  
  JDK环境变量的配置作Java开发的人都应该会,这里就不细讲了!

2.四、Android Studio下载

  下载地址:http://developer.android.com/sdk/index.html,注意,下载Android Studio要FQ才行 编程

  

  

  

  下载完成以后,获得一个以下图所示的安装包: c#

  

2.五、Android Studio安装

  下载完成后,就能够开始安装了,用鼠标双击android-studio-bundle-135.1740770-windows.exe启动安装程序,Android Studio安装过程以下图所示:

  

  AndroidStudio是集成了Android SDK的,因此在安装的时候记得勾选上Android SDK

  

  

  

  

  

  

  这个安装过程有点久,须要一点时间。

  

  

2.六、启动运行Android Studio

  Android Studio启动过程以下图所示:

  

  

  第一次启动AndroidStudio时,须要设置一下SDK的安装目录,所以会弹出以下图所示的对话框,

  

  设置Android SDK的安装目录,以下图所示:

  

  打开AndroidStudio以后,默认会帮咱们建立一个app的项目,以下图所示:

  

  运行这个默认建立好的项目,为了运行方便,咱们直接使用真机做为模拟器运行,以下图所示:

  

  注意,使用真机调试时,手机必须开启USB调试模式才行,以下图所示:

  

  在手机上面的运行结果以下图所示:

  

  手机上显示应用的桌面上也显示出了咱们这个Android应用的图标,以下图所示:

  

  到此,使用Android Studio搭建Android集成开发环境的工做就所有完成了,测试也经过了!

3、Android Studio的简单使用

3.1查看安装好的Android SDK

  

  已经安装好的Android SDK版本以下图所示:

  

  咱们能够看到,截止到今天为止,Anddroid的版本已经更新到Android5.1(API22)了,更新速度真的很快啊,Android5.1(API22)的相关内容如今仍是处于【Not installed】状态,也就是尚未下载和安装,SDK Manager默认已经选中Android5.1(API22)的所有内容,咱们若是想在Android5.1(API22)的平台下开发Android应用,那么能够下载Android5.1(API22)的相关内容,以下图所示:

  

  默认下载和安装好的Android5.0.1的开发包已经知足咱们开发Android应用的需求了,以下图所示:

  

  固然使用eclipse,visual studio也能够开发,具体略


先谈谈其Android的应用架构

能够大体表示为下图。

 

代码被划分为两层结构:Data Layer(数据层)负责从REST API或者持久数据存储区检索和存储数据;View Layer(视图层)的职责是处理并将数据展现在UI上。

APIProvider提供了一些方法,使Activity和Fragment可以很容易的实现与REST API的数据交互。这些方法使用URLConnection和AsyncTask在一个单独的线程内执行网络请求,而后经过回调将结果返回给Activity。

按照一样的方式,CacheProvider 所包含的方法负责从SharedPreferences和SQLite数据库检索和存储数据。一样使用回调的方式,将结果传回Activity。

存在的问题:

使用这种结构,最主要的问题在于View Layer持有太多的职责。想象一个简单且常见的场景,应用须要加载一个博客文章列表,而后缓存这些条目到SQLite数据库,最后将他们展现到ListView等列表视图上。Activity要作到如下几个步骤:

  1. 经过APIProvider调用loadPosts方法(回调)
  2. 等待APIProvider的回调结果,而后调用CacheProvider中的savePosts方法(回调)
  3. 等待CacheProvider的回调结果,而后将这些文章展现到ListView等列表视图上
  4. 分别处理APIProvider和CacheProvider回调中潜在的异常。

这是一个很是简单的例子,在实际开发环境中REST API返回的数据可能并非View直接须要的。所以,Activity在进行展现以前不得不经过某种方式将数据进行转换或过滤。另外一个常见的状况是,调用loadPosts( )所须要的参数,须要事先从其余地方获取到,好比,须要Play Services SDK提供一个Email地址参数。就像SDK经过异步回调的方式返回Email地址,这就意味着如今咱们至少有三层嵌套的回调。若是继续添加复杂的业务逻辑,这种架构就会陷入众所周知的Callback Hell(回调地狱)

总结:

  • Activitty和Fragment变得很是庞大而且难以维护。
  • 太多的回调嵌套意味着丑陋的代码结构并且不易读懂和理解。若是在这个基础上作更改或者添加新特性会感到很痛苦。
  • 单元测试变得很是有挑战性,若是有可能的话,由于不少逻辑都留在了Activity或者Fragment中,这样进行单元测试是很艰难的。

RxJava驱动的新型架构

咱们使用上文提到的组织架构差很少两年的时间。在那段时间内,咱们作了一些改进,稍微缓解了上述问题。例如,咱们添加了一些Helper Class(帮助类)用来减小Activity和Fragment中的代码,在APIProvider中使用了Volley。尽管作出了这些改变,咱们应用程序的代码仍是不能进行友好的测试,而且Callback Hell(回调地狱)的问题仍是常常发生。

直到2014年咱们开始了解RxJava。在尝试了几个示例项目以后,咱们意识到她可能最终帮助咱们解决掉嵌套回调的问题。若是你还不熟悉响应式编程,能够阅读本文(译者注:译文点这里那些年咱们错过的响应式编程)。简而言之,RxJava容许经过异步流的方式处理数据,而且提供了不少操做符,你能够将这些操做符做用于流上从而实现转换,过滤或者合并数据等操做

考虑到经历了前几年的痛苦,咱们开始考虑,一个新的应用程序体系架构看起来会是怎样的。所以,咱们想出了这个。

 

相似于第一种架构,这种体系架构一样被划分为Data LayerView LayerData Layer持有DataManager和一系列的Helper classe 。View Layer由Android的Framework组件组成,例如,Fragment,Activity,ViewGroup等。

Helper classes(图标中的第三列)有着很是特殊的职责以及简洁的实现方式。例如,不少项目须要一些帮助类对REST API进行访问,从数据库读取数据,或者与三方SDK进行交互等。不一样的应用拥有不一样数量的帮助类,但也存在着一些共性:

  • PreferencesHelper:从SharedPreferences读取和存储数据。
  • DatabaseHelper:处理操做SQLite数据库。
  • Retrofit services:执行访问REST API,咱们如今使用Retrofit来代替Volley,由于它天生支持RxJava。并且也更好用。

帮助类里面的大多数public方法都会返回RxJava的Observable。

DataManager是整个架构中的大脑。它普遍的使用了RxJava的操做符用来合并,过滤和转换从帮助类中返回的数据。DataManager旨在减小Activity和Fragment的工做量,它们(译者注:指Activity和Fragment)要作的就是展现已经准备好的数据而不须要再进行转换了。

下面这段代码展现了一个DataManager方法可能的样子。这个简单的示例方法以下:

  1. 调用Retrofit service从REST API加载一个博客文章列表
  2. 使用DatabaseHelper保存文章到本地数据库,达到缓存的目的
  3. 筛选出今天发表的博客,由于那才是View Layer想要展现的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Observable loadTodayPosts ( ) {
             return mRetrofitService . loadPosts ( )
                     . concatMap ( new Func1 , Observable > ( ) {
                         @ Override
                         public Observable call ( List apiPosts ) {
                             return mDatabaseHelper . savePosts ( apiPosts ) ;
                         }
                     } )
                     . filter ( new Func1 ( ) {
                         @ Override
                         public Boolean call ( Post post ) {
                             return isToday ( post . date ) ;
                         }
                     } ) ;
     }

View Layer中诸如Activity或者Fragment等组件只需调用这个方法,而后订阅返回的Observable便可。一旦订阅完成,经过Observable发送的不一样博客,就可以当即被添加进Adapter从而展现到RecyclerView或其余相似控件上。

这个架构的最后元素就是Event Bus(事件总线)。它容许咱们在Data Layer中发送事件,以便View Layer中的多个组件都可以订阅到这些事件。好比DataManager中的退出登陆方法能够发送一个事件,订阅这个事件的多个Activity在接收到该事件后就可以更改它们的UI视图,从而显示一个登出状态。

为何这种架构更好?

  • RxJava的Observable和操做符避免了嵌套回调的出现。
 
  • DataManager接管了之前View Layer的部分职责。所以,它使Activity和Fragment变得更轻量了。
  • 将代码从Activity和Fragment转移到了DataManager和帮助类中,就意味着使写单元测试变得更简单。
  • 明确的职责分离和DataManager做为惟一与Data Layer进行交互的点,使这个架构变得Test-Friendly。帮助类和DataManager可以很容易的被模拟出来。

咱们还存在什么问题?

  • 对于庞大和复杂的项目来说,DataManager会变得很是的臃肿和难以维护。
  • 尽管View Layer诸如Activity和Fragment等组件变得更轻量,它们让然要处理大量的逻辑,如管理RxJava的订阅,解析错误等方面。

集成MVP

在过去的一年中,几个架构设计模式,如MVP或者MVVM在Android社区内已经愈来愈受欢迎了。经过在示例工程文章中进行探索后,咱们发现MVP,可能给咱们现有的架构带来很是价值的改进。由于当前咱们的架构已经被划分为两个层(视图层和数据层),添加MVP会更天然些。咱们只须要添加一个新的presenter层,而后将View中的部分代码转移到presenter就好了。

 

留下的Data Layer保持不变,只不过为了与这种模式保持一致性,它如今被叫作Model

Presenter负责从Model中加载数据,而后当数据准备好以后调用View中相对应的方法。还负责订阅DataManager返回的Observable。因此,他们还须要处理schedulerssubscriptions。此外,它们还能分析错误代码或者在须要的状况下为数据流提供额外的操做。例如,若是咱们须要过滤一些数据并且这个相同的过滤器是不可能被重用在其余地方的,这样的话在Presenter中实现比在DataManager中或许更有意义。

下面你将看到在Presenter中一个public方法将是什么样子。这段代码订阅咱们在前一节中定义的dataManager.loadTodayPosts( )所返回的Observable。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void loadTodayPosts ( ) {
     mMvpView . showProgressIndicator ( true ) ;
     mSubscription = mDataManager . loadTodayPosts ( ) . toList ( )
             . observeOn ( AndroidSchedulers . mainThread ( ) )
             . subscribeOn ( Schedulers . io ( ) )
             . subscribe ( new Subscriber > ( ) {
                 @ Override
                 public void onCompleted ( ) {
                     mMvpView . showProgressIndicator ( false ) ;
                 }
 
                 @ Override
                 public void onError ( Throwable e ) {
                     mMvpView . showProgressIndicator ( false ) ;
                     mMvpView . showError ( ) ;
                 }
 
                 @ Override
                 public void onNext ( List postsList ) {
                     mMvpView . showPosts ( postsList ) ;
                 }
             } ) ;
     }

mMvpView是与Presenter一块儿协助的View组件。一般状况下是一个Activity,Fragment或者ViewGroup的实例。

像以前的架构,View Layer持有标准的Framework组件,如ViewGroup,Fragment或者Activity。最主要的不一样在于这些组件再也不直接订阅Observable。取而代之的是经过实现MvpView接口,而后提供一些列简洁的方法函数,好比showError( )或者showProgressIndicator( )。这个View组件也负责处理用户交互,如点击事件和调用相应Presenter中的正确方法。例如,我有一个按钮用来加载博客列表,Activity将会在点击事件的监听中调用presenter.loadTodayPosts( )

若是你想看到一个完整的运用MVP基本架构的工做示例,能够从Github检出咱们的Android Boilerplate project。也能够从这里阅读关于它的更多信息Ribot的架构指导

为何这种架构更好?

  • Activity和Fragment变得很是轻量。他们惟一的职责就是创建/更新UI和处理用户事件。所以,他们变得更容易维护。
  • 如今咱们经过模拟View Layer能够很容易的编写出单元测试。以前这些代码是View Layer的一部分,因此咱们很难对它进行单元测试。整个架构变得测试友好。
  • 若是DataManager变得臃肿,咱们能够经过转移一些代码到Presenter来缓解这个问题。

咱们依然存在哪些问题?

  • 当代码库变得很是庞大和复杂时,单一的DataManager依然是一个问题。虽然咱们尚未走到这一步,但这是一个真正值得注意的问题,咱们已经意识到了这一点,它可能发生。

值得一提的是它并非一个完美的架构。事实上,不要天真的认为这是一个独特且完美的方案,可以解决你全部的问题。Android生态系统将保持快速发展的步伐,咱们必须继续探索。不断地阅读和尝试,这样咱们才能找到更好的方法来继续构建优秀的Android应用程序。

最后多实践,发现秘密。

adiOS

相关文章
相关标签/搜索