本blog介绍mvp模式的特点与优点,为了方便理解 举了用mvp模式实现的两个例子,例一偏向简单用于原理说明,例二应用现在比较火的Retrofit和RXJava进行网络数据请求的mvp模式实例。
1、MVP模式:
2、MVP模式 VS MVC模式
(1)各个层之间通过接口协议进行沟通。
(2)View和Model不再进行直接交互
3、MVP优势:
(1)View和Model之间的耦合度降低,使各自更关注自身业务。
(2)便于单元测试。
(3)代码复用率提高。
(4)代码框架更适用于快速迭代开发。
4、-----------------------------实例1
项目结构:
View层:
public class BaseViewActivity extends AppCompatActivity implements BaseView{
private BasePresenterImpl mPresenter;
boolean flag;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPresenter = new BasePresenterImpl(this);
Log.e("JS","进入 view 层 1");
//开始请求服务
mPresenter.loadData();
Log.e("JS","进入 view 层 2");
//加载完成
mPresenter.loadResult();
}
@Override
public void loading() {
Log.e("JS","开启 进入view层 iterface 事件");
}
@Override
public void cancelLoading() {
Log.e("JS","结束 进入view层 iterface 事件");
}
}
//UI逻辑接口,一般由activity、fragment实现
public interface BaseView {
//显示加载进度
void loading();
//隐藏加载进度
void cancelLoading();
}
public class BasePresenterImpl implements BasePresenter{
private BaseView mView;
private BaseModel mModel;
public BasePresenterImpl(BaseView view){
mModel = new BaseModelimpl();
this.mView = view;
}
// 调用view层和model层来 加载数据
public void loadData(){
Log.e("JS","model/view------->presenter ");
mView.loading();//访问view层
mModel.RequestService();//访问model层
Log.e("JS","-----可得到 view和model return 的数据-------");
}
@Override
public void loadResult() {
Log.e("JS","presenter ---------> view ");
mView.cancelLoading();
}
}
/**处理业务逻辑
* Created by apple on 17/4/27.
*/
public interface BasePresenter {
//加载数据结果
void loadResult();
}
public class BaseModelimpl implements BaseModel {
@Override
public void RequestService() {
Log.e("JS","开启 进入model层 interface");
}
}
public interface BaseModel {
//请求服务器
void RequestService();
}
打印信息:
实例2-----------------
retrofit和rxJava结合的mvp实例
1、view层接口
import com.example.apple.retrofit.MVP.bean.IpBean;
/**
* Created by apple on 17/5/4.
*/
public interface interView {
public void showInfo(IpBean ipBean);
public void showError(Throwable e);
}
import com.example.apple.retrofit.MVP.bean.IpBean;
import com.example.apple.retrofit.MVP.presenter.Presenter;
import com.example.apple.retrofit.MVP.presenter.interPresenter;
import com.example.apple.retrofit.R;
/**
* Created by apple on 17/5/4.
*/
public class MainActivity extends Activity implements interView{
private TextView ipInfo;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ipInfo = (TextView) findViewById(R.id.ipInfo);
interPresenter presenter = new Presenter(this);
presenter.queryIpInfo("121.33.6.228");//调用presenter层的接口方法
}
@Override
public void showInfo(IpBean ipBean) {
String aa = ipBean.area+ipBean.city+ipBean.country+ipBean.ip+ipBean.region;
Log.e("jj",aa);
ipInfo.setText(aa);
}
@Override
public void showError(Throwable e) {
}
}
public interface interPresenter {
public void queryIpInfo(String ip);
}
public class Presenter implements interPresenter{
//在presenter层,引入model层和view层。
private interView viewActivity;
private interModel model;
public Presenter(MainActivity viewActivity){
this.viewActivity = viewActivity;
model = new Model();
}
@Override
public void queryIpInfo(String ip) {
//观察者位于presenter层,通知主线程
Subscriber> mySubscriber = new Subscriber>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
viewActivity.showError(e);
}
@Override
public void onNext(ApiBean ipBeanApiBean) {
//获取来自被观察者model层传来的ipBeanApiBean,并调用view层方法
viewActivity.showInfo(ipBeanApiBean.data);
}
};
model.queryIpInfo(ip,mySubscriber);//调用model接口方法
}
}
3、model层接口
public interface interModel {
public void queryIpInfo(String ip, Subscriber> subscriber);
}
public interface InterfRetrofit {
@GET("service/getIpInfo.php")
Call> getMessage(@Query("ip") String ip);
}
public class Model implements interModel{
@Override
public void queryIpInfo(final String ip, Subscriber> subscriber) {
//被观察者做耗时操作,位于model层
Observable> myObserverble =
Observable.create(new Observable.OnSubscribe>() {
@Override
public void call(Subscriber super ApiBean> subscriber) {
//在rxjava的observable中,添加一个retrofit,进行网络请求 具体耗时操作由它执行
String URL_BASE = "http://ip.taobao.com";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL_BASE)
.addConverterFactory(GsonConverterFactory.create())
.build();
InterfRetrofit interfRetrofit = retrofit.create(InterfRetrofit.class);
Call> call = interfRetrofit.getMessage(ip);
try {
Response> response = call.execute();
ApiBean apiResponse = response.body();
//将apiResponse传给观察者presenter
subscriber.onNext(apiResponse);
} catch (IOException e) {
e.printStackTrace();
subscriber.onError(e);
}finally {
subscriber.onCompleted();
}
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
myObserverble.subscribe(subscriber);
}
}
public class ApiBean implements Serializable {
//结果
public int code;
//数据
public T data;
}
import com.google.gson.annotations.SerializedName;
public class IpBean {
//国家
public String country;
//国家代码
@SerializedName("country_id")
public String countryId;
//地区
public String area;
//地区代码
@SerializedName("area_id")
public String areaId;
//省份
public String region;
//省份代码
@SerializedName("region_id")
public String regionId;
//城市
public String city;
//城市代码
@SerializedName("city_id")
public String cityId;
//区
public String county;
//区号
@SerializedName("county_id")
public String countyId;
//运营商
public String isp;
//运营商代码
@SerializedName("isp_id")
public String ispId;
//IP地址
public String ip;
}