MVP实践
文章目录:
MVP介绍
MVP概念
Model:层是数据访问层,用于数据库查询或者远程服务器访问
View:用于界面的显示以及用户交互,在Android里面View通常就是Actvitiy,Fragment,当然,也有人将Activity,Fragment用作Present,因为他们生命周期比较复杂,将他们作为Presenter可以少去许多生命周期的考虑。
Presenter:是View跟Model的桥梁,也是MVP种最难最重要的一环,同时Presenter也用于控制model层数据操作所在的线程。
MVP的优点
相对于我们之前常用的MVC模型,MVP模型是完全隔离了 数据层 和 View层,下面两个图就和形象突出了MVP的优点:
view层和数据层如果不隔离,View处理代码会变得非常复杂,而且代码耦合度高,维护成本高
View层和数据层隔离,结构变得简单
所以,MVP的优点一目了然,可以减少代码耦合,易于维护。
实践
下面,我们来实践下MVP,重构之前 查询PM2.5的程序
效果如下图:
逻辑比较简单,就是用户输入城市名称,点击查询按钮,通过天气API查询天气,获取结果后显示在界面中,下面我们一步步来写空气质量获取显示的相关代码
Model层
public interface ICallback { //1.空气质量获取相关回调
public void onResult(String data);
public void onFail(String data);
}
public class PM25Model { //2.获取PM2.5数据并返回数据
public static void getData(String CityName, ICallback callback) {
PM25VolleyRequest.newInstance().GetPM25Value(CityName,callback);
}
}
1.获取空气质量回调,这里的回调,是M -> P ->V的关键
2.通过GetPM25Value接口并将结果通过callback向P/V层传递
View层
public interface PM25View { //3.View层需要实现的接口
void getPM25Success(String s);
void getPM25Fail(String s);
}
public class PM25Activity extends MVPBaseActivity<PM25Presenter> implements PM25View{
private final static String TAG = "PM25Activity";
@Bind(R.id.tv2)
TextView mTv;
@Bind(R.id.et)
AutoCompleteTextView mEt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_pm25);
setTitle("PM25Demo");
}
@Override
protected PM25Presenter createPresenter() { //4.初始化Presenter
return new PM25Presenter(this);
}
@OnClick(R.id.btn)
void checkPM25(){ // 5.处理点击事件
String mCityName = mEt.getText().toString();
if ("".equals(mCityName)) {
mCityName = getString(R.string.cityname_guangzhou);
}
mvpPresenter.onClickToCheckPM25(mCityName);
}
@Override
public void getPM25Success(String s) { //6.获取数据后渲染UI
mTv.setText(s);
}
@Override
public void getPM25Fail(String s) { //6.获取数据后渲染UI
mTv.setText(s);
}
}
3.View层需要实现的接口
4,5.代码中一共有两处用到Presenter, 一个是4中的初始化Presenter,处理生命周期相关的操作,另外一个是处理用户点击事件,将点击事件处理放到Presenter中来执行
6.获取数据后渲染UI,MVP模型并不是说数据和界面就完全没关系了,相反,View需要数据来渲染UI,与用户实现交互
Presenter层
PM25Model model;
public class PM25Presenter extends BasePresenter<PM25View> {
public PM25Presenter(PM25View view) { //7.初始化View
model = new PM25Model();
attachView(view);
}
@Override
public void onClickToCheckPM25(String mCityName){ //8.从View中获取城市名
model.getData(mCityName, new ICallback() { //9.将城市名出入model中
@Override
public void onResult(String data) {
mvpView.getPM25Success(data); //10.将获取的信息出入View中,显示出来
}
@Override
public void onFail(String data) {
mvpView.getPM25Fail(data);
}
});
}
}
7.将View出入Presenter中,方便View更新
8.View中传递点击事件,也是步骤5中传入的参数
9.将从View获取的城市名称传入model中,这里就实现了数据 V->P->M的传递,在这里,P还可以控制M中操作的线程,但是因为我是使用Gson Queue,所以并没有做相关操作,都是在model中完成线程操作的
10.Model中返回处理之后的数据并通过P层传递给View,流畅为 M->P ->V,如果数据需要加工,可以在P层中处理
回顾下流程:
代码可以到这里下载,免积分哦~ 在代码中还包含了对城市信息补全功能的重构,欢迎下载