在之前安卓日記——手把手教你做知乎日報已經教大家分析和利用API做出一個簡單的知乎日報,源碼在github上也收到了5個star
最近我一直很想用一下一直很玄乎的MVP,主要參照谷歌的todo-mvp-rxjava
然后我就想不如就把知乎日報用MVP重構一下吧
我理解中的MVP,以數據庫或者網絡請求作為M(通常多個共用,所以不單獨寫)一個Fragment或者Activity作為V,然后把之前的業務邏輯都寫在P里。
有人把P當作老板,去指使M和V
而我認為V才是大BOSS,V中創建P,然后把些粗活累活都交給P,P把數據獲取外包給M,然后V說我只要看到結果,接收到P傳來的結果,就心滿意足了
項目可以按照模塊分包(登錄功能,注冊功能……),也可以按照組件分包(P分一類,V分一類……)
我模仿谷歌的todo-mvp-rxjava采用模塊分包
我看過很多mvp的項目,他們很多是按組件分包的,而且他們都沒有一個Contract
在我看來Contract是很有必要的,有了它把職責的分明了,互相調用的方法暴露出來,這樣開發的目的會更加明確,分工也更加簡單
事不宜遲,現在開始講如何進行重構
我假設你們都已經懂得如何用我之前的方法做一個知乎日報
1.分析功能模塊
這里主要有首頁和詳情頁兩個模塊
2.寫基類
基類不僅節省代碼,提高效率,這個不用說了吧
如
public interface BasePrecenter {
void subscribe();
void unsubscribe();
}
public interface BaseView<T extends BasePrecenter> {
void setPrecenter(T precenter);
}
3.寫Contract
Contract中可以不包含M,因為M通常都是公用的,所以單獨放,我這Service就是M,主要是網絡請求數據
如
public interface ArticleContract {
interface View extends BaseView<Precenter>{
void showAtrticleDetail(String content);
}
interface Precenter extends BasePrecenter{
void loadArticleDetail(int id);
}
}
4.寫Bean和Model
確定好數據的格式和獲取的方式
我這里采用的是用retrofit獲取數據
public interface ActionService {
public static String baseUrl="http://news-at.zhihu.com";
//今日頭條
@GET("/api/4/news/latest")
Observable<RootBean> getLatestNews();
//互聯網安全
@GET("/api/4/theme/10")
Observable<RootBean> getSafety();
//不準無聊
@GET("/api/4/theme/11")
Observable<RootBean> getInterest();
//體育日報
@GET("/api/4/theme/8")
Observable<RootBean> getSport();
//傳入id查看詳細信息
@GET("/api/4/news/{id}")
Observable<ArticleDetailBean> getNewsDetails(@Path("id") int id);
}
5.然后再寫P和V
V中創建P,創建P需要傳入V
//創建P傳入V
precenter=new HomePrecenter(this);
setPrecenter(precenter);
P中綁定V,并且創建M
public HomePrecenter(HomeContract.View view){
//綁定V
this.view=view;
//創建M
service= ServiceFactory.createRetrofitService(ActionService.class,ActionService.baseUrl);
}
之后主要是一些互相調用Contract中約定好的方法
補充:
P中有subscribe和unsubscribe方法可以與V中的onResume和onPause方法綁定
這樣V開始時繼續P的業務,暫停時停止P的邏輯
@Override
public void onResume() {
super.onResume();
precenter.subscribe();
}
@Override
public void onPause() {
super.onPause();
precenter.unsubscribe();
}
}
P中將要執行的業務都添加進CompositeSubscription中,unsubscribe時把CompositeSubscription清空掉
如
subscription.add(rootBean
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<RootBean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(RootBean rootBean) {
view.showArticle(rootBean.getStories());
}
}));
@Override
public void unsubscribe() {
subscription.clear();
}
重構后竟然一次通過了,太興奮了