系列文章:
1-准备工作
2-搭建项目框架
3-功能实现
4-加入网络缓存
请先阅读MVP架构实现的Github客户端(1-准备工作). 本文承接上文, 主要介绍项目框架搭建.
废话少说, 放码过来
1, 提取一个mvp模块
提取MVP中View/Presenter相关接口到一个独立的mvp模块(可复用):
包结构
类图
简单说明
一个MvpView接口来约束View组件:
public interface MvpView {
}
MvpPresenter接口中关联MvpView:
public interface MvpPresenter {
/**
* Set or attach the view to this presenter
*/
@UiThread
void attachView(V view);
/**
* Will be called if the view has been destroyed. Typically this method will be invoked from
* Activity.detachView()
or Fragment.onDestroyView()
*/
@UiThread
void detachView();
}
另外, 由于现在App的内容展示大部分是基于网络数据, 在此扩展了一个通用的LceView, Lce取Loading, Content, Error之意:
public interface LceView extends MvpView {
@UiThread
public void showLoading();
@UiThread
public void dismissLoading();
@UiThread
public void showContent(M data);
@UiThread
public void showError(Throwable e);
}
2, 搭建app框架
包结构
app框架方面, 个人主张是先基于MVP架构分包 然后根据业务功能划分模块的, 如下:
其中:
-
common
- 包含util, config, constant等通用包和类.
-
data
- 包含model, api, db, pref, 网络接口实现等.
- 其中对外公开一个DataRepository提供业务接口相关数据.
-
di
- 依赖注入相关的类.
- 根据dagger2的风格, 一般有module和component模块.
-
presenter
- 里面根据业务模块划分.
-
ui
- 包含UI层的所有东东. activity, fragment, widget, dialog, adapter等, 根据需求不同分包方式有出入.
层次结构
层次结构相对与业务需求而言, 例如账户相关的登录注册, repo模块相关的repo列表, 详情等...
大体上每个业务模块都会由以下几个部分构成, 整体的项目层次也是如此:
3, 完善基础工程
根据上述两步, 一个项目的基本架构已经完成, 但是并不完整, 我们还需要添加一些通用类, 基础类来完善下. 其实这些基类也相当于是一个编码规范, 特别是多人合作项目中, 提前根据项目需求写一些通用类, 工具类, 基类等, 能够避免后续大家编码上各自一套. 所以个人认为这些类的编写也属于搭建框架的一部分.
添加相关Base类
为了便于统一处理, 惯例, 我们需要为Activity, Fragment创建一个BaseActivity, BaseFragment. 可以在ui包里创建一个base子包放置.
这个基类好处多多, 例如我们对界面的统一处理, 生命周期的日志打印, 添加统计工具等, 都能很方便的再基类里面处理.
封装相关工具类
如上文所说, 个人习惯对第三方开源库再做一层封装, 以便后续灵活替换.
使用过程中, 也只需调用封装后的接口即可, 无需关注具体的依赖包. 也利于大家协作统一.
例如:
- Logger封装
创建一个AppLog类来包装Logger:
public class AppLog {
private static final String TAG = "GithubApp";
/**
* initialize the logger.
*/
public static void init() {
Logger.init(TAG);
}
/**
* log.i
* @param msg
*/
public static void i(String msg) {
if (BuildConfig.DEBUG) {
Logger.i(msg);
}
}
/**
* log.d
* @param msg
*/
public static void d(String msg) {
if (BuildConfig.DEBUG) {
Logger.d(msg);
}
}
/**
* log.w
* @param msg
*/
public static void w(String msg) {
if (BuildConfig.DEBUG) {
Logger.w(msg);
}
}
/**
* log.e
* @param msg
*/
public static void e(String msg) {
Logger.e(msg);
}
}
- 图片加载库封装
封装一个ImageLoader工具类来对外提供接口加载图片:
public class ImageLoader {
/**
* Load image from source and set it into the imageView. Use Glide now.
* @param context context.
* @param source could be Uri/String/File/ResourceId.
* @param view the imageView.
*/
public static void load(Context context, Object source, ImageView view) {
Glide.with(context)
.load(source)
.centerCrop()
.into(view);
}
}
Dagger相关基础类
因为我们使用的Dagger2来做依赖注入, 因为Activity和Application的Context是比较常用的, 我们会构建Activity, Application相关的component/module来提供对应的Context.
具体代码参看github工程源码.
4, 整体结构
假设我们的产品需要是迭代式的, 至此, 我们的基础框架已经差不多了(不建议做过多过早设计).
回顾下, 大体结构现在基本如下:
mvp
app
具体代码请参看https://github.com/mingjunli/GithubApp
目前代码只是一个基础的框架, 心急的同学可以参看这个工程, 架构类似. 一个简单的新闻客户端, 用来做MVP demo的.