原文地址: http://www.jianshu.com/p/48e66e879061
前言
今年的Android技术圈中
MVP
,Dagger2
,Rxjava
,Retrofit
这些词汇非常火,随便打开一个技术论坛都充斥着大量的关于这些技术的文章,Github
也充斥着各种以基于MVP+Retrofit+RxJava+Dagger2+MaterialDesign开发的xxxx
为标题的开源项目或Demo.但是大家这么热心的开源此类项目,一直重复的做着同样的事
教授大家使用的方式和技巧
有没有想过依赖一个第三方库,就可以快速的搭建此类框架?
What is MVPArms?
MVPArms
是一个集成了大量Android主流框架,并且全部使用Dagger2管理,以及提供API将所有库连接起来方便使用,还提供详细的Wiki文档.它可以使开发后面的所有项目都不用重复的复制粘贴(用过此类框架的朋友应该知道,这些库都依赖其它的库,就算一个build.gradle都会浪费很多时间),一个依赖省去很多烦恼,而且对于新手来说这些框架难的不仅仅是API的使用,更难的是怎么把它们结合到一起,应对各种场景的使用.
对于一个新的Android项目,特别是熟练使用Dagger2和Rxjava的开发者,你们只需要将此项目Clone下来,Demo只实现了一个页面,将此页面删除掉,添加所需要的Retrofit API,你的框架就搭建好了,你就可以直接使用Demo进行后续的开发,包结构也适合后面的扩展.
Notice
沟通交流群: QQ群 455850365 | 301733278
-
一键生成模板, 开发神器, 不看后悔! (MVPArms 的所有规范现已整合到以下两种模板中, 让您无需理解 Wiki 文档便可快速开启 MVPArms 的世界)
扩展项目, 了解一下:
Feature
通用框架, 适合所有类型的项目, 支持大型项目的开发, 兼容组件化开发, 可作为组件化的 Base 库
Base 基类(BaseActivity, BaseFragment, BaseApplication ...)
MVP 基类(IModel, IVIew, IPresenter ...)
框架高度可自定义化 (ConfigModule), 可在不修改框架源码的情况下对 Retoift, Okhttp, RxCache, Gson 等框架的特有属性进行自定义化配置, 可在不修改框架源码的情况下向 BaseApplication, BaseActivity, BaseFragment 的对应生命周期中插入任意代码, 并且框架独有的 ConfigModule 配置类, 可在不修改框架源码的情况下为框架轻松扩展任何新增功能
独创的 RxLifeCycle 应用方式, 可在不继承 RxLifeCycle 提供的 Activity 和 Fragment 的情况下, 正常使用 RxLifeCycle 的所有功能, 且使用方式不变
独创的建造者模式 Module (GlobalConfigModule), 可实现使用 Dagger2 向框架任意位置注入自定义参数, 可轻松扩展任意自定义参数
全局使用 Dagger2 管理 (将所有模块使用 Dagger2 连接起来, 绝不是简单的使用)
全局监听整个 App 所有 Activity 以及 Fragment 的生命周期 (包括三方库), 并可向其生命周期内插入任意代码
全局监听 Http Request(请求参数, Headers ...), Response (服务器返回的结果, Headers, 耗时 ...)等信息(包括 Glide 的请求), 可解析 json 后根据状态码做相应的全局操作以及数据加密, Cookie 管理等操作
全局管理所有 Activity (包括三方库的 Activity), 可实现在整个 App 任意位置, 退出所有 Activity, 以及拿到前台 Activity 做相应的操作(如您可以在 App 任何位置做弹出 Dialog 的操作)
全局 Rxjava 错误处理, 错误后自动重试, 捕捉整个应用的所有错误
全局 UI 自适应
图片加载类 ImageLoader 使用策略模式和建造者模式, 轻松切换图片加载框架, 方便功能扩展
网络请求日志打印封装(提供解析后的服务器的请求信息和服务器的响应信息, 按可自定义的任意格式输出打印日志, 内置一个漂亮的打印格式模板)
框架内自有组件的缓存机制封装(框架内可缓存内容的组件都提供有接口供外部开发者自定义缓存机制)
代码生成插件(MVPArms 全家桶一键生成所需要的所有类文件)
Demo 修改包名后就可以直接使用, 快速接入
Where?
Architectural
Package Structure
How?
Wiki
Contract
根据
Dagger
注入Presenter无需定义Presenter接口,所以Contract只定义Model和View的接口
public interface UserContract {
//对于经常使用的关于UI的方法可以定义到BaseView中,如显示隐藏进度条,和显示文字消息
interface View extends BaseView {
void setAdapter(DefaultAdapter adapter);
void startLoadMore();
void endLoadMore();
}
//Model层定义接口,外部只需关心model返回的数据,无需关心内部细节,及是否使用缓存
interface Model {
Observable<List<User>> getUsers(int lastIdQueried, boolean update);
}
}
View
一般让Activity或Fragment实现Contract中定义的View接口,供Presenter调用对应方法操作UI,BaseActivity默认注入Presenter,如想使用Presenter,必须指定Presenter的范型,和实现setupActivityComponent来提供Presenter需要的Component和Module
public class UserActivity extends WEActivity<UserPresenter> implements UserContract.View {
@Override
protected void setupActivityComponent(AppComponent appComponent) {
DaggerUserComponent
.builder()
.appComponent(appComponent)
.userModule(new UserModule(this))
.build()
.inject(this);
}
@Override
protected View initView() {
return LayoutInflater.from(this).inflate(R.layout.activity_user, null, false);
}
@Override
protected void initData() {
}
}
Model
Model实现Contract的Model接口,并且继承BaseModel,指定范型为ServiceManager和CacheManager,然后通过两个Manager拿到需要的Service和Cache为Presenter提供需要的数据(是否使用缓存请自行选择,Presenter无需关心细节)
public class UserModel extends BaseModel<ServiceManager,CacheManager> implements UserContract.Model{
private CommonService mCommonService;
private CommonCache mCommonCache;
public UserModel(ServiceManager serviceManager, CacheManager cacheManager) {
super(serviceManager, cacheManager);
this.mCommonService = mServiceManager.getCommonService();
this.mCommonCache = mCacheManager.getCommonCache();
}
@Override
public Observable<List<User>> getUsers(int lastIdQueried, boolean update) {
}
}
Presenter
Presenter在MVP中的大部分的作用为通过从Model层接口获取数据,在调用View层接口显示数据,首先实现BasePresenter,指定Model和View的范型,注意一定要指定Contract中定义的接口,Presenter需要的Model和View,都使用Dagger2注入,这样即解藕又方便测试,怎么注入?
@ActivityScope
public class UserPresenter extends BasePresenter<UserContract.Model, UserContract.View> {
@Inject
public UserPresenter(UserContract.Model model, UserContract.View rootView) {
super(model, rootView);
}
//这里定义业务方法,相应用户的交互
public void requestUsers(final boolean pullToRefresh) {
}
}
Acknowledgement
感谢本框架所使用到的所有三方库的Author,以及所有为
Open Sourece
做无私贡献的Developer和Organizations,使我们能更好的工作和学习,本人也会将业余时间回报给开源社区
Mvp
是 Google 官方出品的Mvp
架构项目,含有多个不同的架构分支(此为 Dagger 分支).Dagger2
是 Google 根据 Square 的 Dagger1 出品的依赖注入框架,通过 Apt 编译时生成代码,性能优于使用运行时反射技术的依赖注入框架.RxJava
提供优雅的响应式 API 解决异步请求以及事件处理.RxAndroid
为 Android 提供响应式 API.Rxlifecycle
,在 Android 上使用RxJava
都知道的一个坑,就是生命周期的解除订阅,这个框架通过绑定 Activity 和 Fragment 的生命周期完美解决该问题.RxCache
是使用注解,为Retrofit
加入二级缓存 (内存,磁盘) 的缓存库.RxErroHandler
是RxJava
的错误处理库,可在出现错误后重试.RxPermissions
用于处理 Android 运行时权限的响应式库.Retrofit
是 Square 出品的网络请求库,极大的减少了 Http 请求的代码和步骤.Okhttp
同样 Square 出品,不多介绍,做 Android 的都应该知道.AndroidAutoSize
是今日头条屏幕适配方案终极版,一个极低成本的 Android 屏幕适配方案,该库没有引入到Arms
,所以框架使用者可自由选择屏幕适配方案.Gson
是 Google 官方的 Json Convert 框架.Butterknife
是 JakeWharton 大神出品的 View 注入框架.AndroidEventBus
是一个轻量级的 EventBus,该库没有引入到Arms
,所以框架使用者可自由选择 EventBus.Timber
是 JakeWharton 大神出品的 Log 框架容器,内部代码极少,但是思想非常不错.Glide
是本框架默认封装到扩展库arms-imageloader-glide
中的图片加载库,可参照着 Wiki 更改为其他的图片加载库,Glide
的 API 和Picasso
差不多,缓存机制比Picasso
复杂,速度快,适合处理大型图片流,支持 gif 图片,Fresco
太大了!在 5.0 以下优势很大,5.0 以上系统默认使用的内存管理和Fresco
类似.LeakCanary
是 Square 出品的专门用来检测Android
和Java
的内存泄漏,并通过通知栏提示内存泄漏信息.
公众号
扫码关注我的公众号 JessYan,一起学习进步,如果框架有更新,我也会在公众号上第一时间通知大家
Hello 我叫 JessYan,如果您喜欢我的文章,可以在以下平台关注我
- 个人主页: http://jessyan.me
- GitHub: https://github.com/JessYanCoding
- 掘金: https://juejin.im/user/57a9dbd9165abd0061714613
- 简书: http://www.jianshu.com/u/1d0c0bc634db
- 微博: http://weibo.com/u/1786262517
-- The end