系列文章:
1-準備工作
2-搭建項目框架
3-功能實現
4-加入網絡緩存
請先閱讀MVP架構實現的Github客戶端(1-準備工作). 本文承接上文, 主要介紹項目框架搭建.
廢話少說, 放碼過來
1, 提取一個mvp模塊
提取MVP中View/Presenter相關接口到一個獨立的mvp模塊(可復用):
包結構
類圖
簡單說明
一個MvpView接口來約束View組件:
public interface MvpView {
}
MvpPresenter接口中關聯MvpView:
public interface MvpPresenter<V extends MvpView> {
/**
* 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
* <code>Activity.detachView()</code> or <code>Fragment.onDestroyView()</code>
*/
@UiThread
void detachView();
}
另外, 由于現在App的內容展示大部分是基于網絡數據, 在此擴展了一個通用的LceView, Lce取Loading, Content, Error之意:
public interface LceView<M> 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的.