# 序

> 只因无意间多看了一眼 [Android Application Architecture](https://labs.ribot.co.uk/android-application-architecture-8b6e34acda65#.5sblaoy3i), 从此便一发不可收拾. [译文](http://www.jianshu.com/p/8ca27934c6e6)

![Android](/files/-LsLm8J125C4SUlCHche)

正式从事Android开发工作已经一年多了, 原先使用的架构(开发)模式随着项目的增多, 经验的积累已经变得力不从心. 其间架构模式也在原先的基础上变动重构过几次, 但也都是不痛不痒的累加库与工具类, 于是催生了研究新的开发架构模式的想法. 继而催生了本书 (勉强可以算是书) 的诞生, 以此记录我研究各路架构的心路历程. 一来是对知识与设计思路的总结, 二来锻炼自己的写作表达能力, 三来也可以当作Api来参考使用.

### 旧的模式

* IDE - Eclipse + ADT
* 包结构 - 按类别分包 如activity, fragment, adapter等
* 网络 - 封装过的Volley + Gson
* 图片加载 - 使用Volley自定义的带缓存的ImageView控件
* 下拉刷新 - handmark pulltorefresh

旧模式由于没有使用过多的额外的框架或者库, 所以结构相对简单干净, 也不太需要考虑64k方法上限的限制. 对于经验不太丰富的开发人员来说上手也会比较简单.

但是优点也是旧模式的缺陷:

* Eclipse + ADT的优缺点就不多赘述了, 网上有很多相关文章.
* 由于使用的是Android原生的设计模式, 导致`Acivity`/`Fragment`等界面元素的职责过多, 代码随着时间以及需求的变更越积越多, 最终变得难以维护.
* 按类别分包会导致查找文件困难. 稍微复杂一点的项目`Activity`都会有4,50个, 可以想象在这么多`Activity`中找一个是多么蛋疼.
* 封装的Volley可以使用通用的Api很方便的发网络请求, 但是需要在`Activity`/`Fragment`中拼接请求参数`HashMap`, `Activity`/`Fragment`会多了不少重复的代码.
* 加载网络图片需要使用自定义的`ImageView`, 比较麻烦, 并且不能很方便的更换缓存策略. 无法对图片做压缩, 变换等处理.
* handmark pulltorefresh是一个经典的下拉刷新库, 但是扩展新的下拉组件会比较复杂. 并且该控件不能在`height`上使用`wrap_content`或者设置`visibility`为`gone`, 否则加载不出视图. 由于使用的`addHeaderView`的方式来添加下拉头部, 理论上不能支持任意的控件.

### 改进后的模式

因为以上缺陷, 我在使用过程中对其做了一些改进:

* 包结构从按类分包改为按功能分包, 比如用户相关的页面放在`user`包下.
* 将所有通用的库, 工具类单独放到一个Library工程 (CoreLibs) 中, 项目主工程来引用这个库工程. 这也是CoreLibs的初始形态. 这样做的好处是当频繁地有新项目的时候 (大约1,2个月来一个新项目) 可以很方便的创建新的空白工程并直接通过引用库来添加必要的文件. 缺点就是项目多了会有多个CoreLibs副本, 同时维护会很耗费精力.
* 参照经典的MVC模式, 在原来的基础上加入了Model层将拼接请求参数, 请求地址等逻辑从`Activity`/`Fragment`中移除. 相关的接口都放入一个`Manager` (个人习惯, 即是`Model`) 类中, 比如`UserManager`, `ProductManager`等. `Manager`类中定义了接口的信息, 如请求参数, 接口地址, 回调等.
* 所有网络请求参数, 如请求参数, 接口地址, Gson解析类型等信息封装成`NetworkParams`类, 采用简化的Builder模式, 链式调用, 方便在`Manager`中描述接口信息.
* 图片加载引入了Square的Picasso, 此库的特点是Square出品, 必属精品\~ 轻量, 使用方便简单等等...
* 引入NineOldAndroids动画库, 使得3.0以下的系统也可以兼容属性动画的API.

这时的模式虽然有一些改进, 但是一些问题还不能完美解决, 比如`Activity`/`Fragment`虽然没了Model层的逻辑, 但是还是负责界面以及逻辑控制, 也就是同时承担M与C的角色. 因此促进的新的架构模式的诞生.

### 新的模式

* 从Eclipse迁移到Android Studio
* 引入MVP模式.
* 网络请求由Volley改为Retrofit.
* 引入RxJava, RxAndroid.
* pulltorefresh由handmark改为Ultra-PullToRefresh.
* 引入ButterKnife.
* 引入RxBus事件驱动.
* 其他常用工具库.

新的模式最重要的就是引入了MVP以及Retrofit + Rxjava. 至于为何会引入这些模式与库后续会有篇幅一一介绍. 目前整个架构就像简介中描述的一样, MVP-based, RxJava, RxAndroid, Retrofit, Picasso, ButterKnife, RxBus, NineOldAndroids.

#### CoreLibs的源码以及引入方法请参考 [GitHub-CoreLibs](https://github.com/TheseYears/CoreLibs)

> 目前架构正在不断探索中, 所以我会不定时更新. 但由于我经验有限, 文中肯定会有描述错误或不准确的地方, 如果发现还请不吝啬指教.

## 通过以下方式联系我:

* Email:  fengxidadi at gmail/163 .com
* GitHub: <https://github.com/theseyears>

**`by Ryan`**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ryan-8.gitbook.io/android-architecture-journey/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
