在之前安卓日记——手把手教你做知乎日报已经教大家分析和利用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();
}
重构后竟然一次通过了,太兴奋了