一、为什么使用MVP模式
在Android开发中,Activity并不是标准的MVC模式中的controller,它的首要职责是加载应用布局,处理用户操作并做出响应。随着界面及逻辑的复杂度不断提升,Activity的职责便不断增加,导致整个类变得庞大臃肿。因此我们需要将复杂的逻辑处理放到另一个类Presenter中,而Activity只负责处理用户操作并响应。
二、什么是MVP模式
MVP(模式-视图-主导器)模式是由MVC(模型-视图-控制器)模式衍生的。在MVP中,视图中的业务逻辑被放到主导器中,主导器通过接口与视图交互,减低耦合,同时也方便单元测试。
M(Model,模式):负责存储,检索等复杂操作;
V(View,模式):负责绘制UI元素,与用户交互,例如Activity;
P(Presenter,主导器):作为View和Model的中间纽带,负责与用户交互的逻辑,通过接口实现。
三、MVP使用实例
程序开始会检查网络是否连接,如果网络正常,则正常主页面,否则显示网络异常的画面。
程序结构如下:
Model层定义接口如下
public interface INetworkStatus {
boolean isOnline(Activity activity);
}
Model实现如下:
public class NetworkStatus implements INetworkStatus {
@Override
public boolean isOnline(Activity activity) {
// TODO Auto-generated method stub
Context context = activity.getApplicationContext();
// 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
return false;
} else {
// 获取NetworkInfo对象
NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();
if (networkInfo != null && networkInfo.length > 0) {
for (int i = 0; i < networkInfo.length; i++) {
// 判断当前网络状态是否为连接状态
if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
}
View定义接口如下
public interface IMainView {
/** 显示进度条 */
void showProgress();
/** 隐藏进度条 */
void hideProgress();
/** 显示网络异常信息 */
void showNetworkError();
/** 网络联通,正常显示数据 */
void showDataNormal();
}
View的实现通常就是一个Activity对象,如下:
public class MainActivity extends Activity implements IMainView {
ProgressDialog progressDialog = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void showProgress() {
// TODO Auto-generated method stub
progressDialog = ProgressDialog.show(this, "Loading...",
"Please wait...", true, false);
}
@Override
public void hideProgress() {
// TODO Auto-generated method stub
if (progressDialog != null) {
progressDialog.dismiss();
progressDialog = null;
}
}
@Override
public void showNetworkError() {
// TODO Auto-generated method stub
new AlertDialog.Builder(this).setTitle("网络状态").setMessage("网络异常,请检查网络")
.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
}
@Override
public void showDataNormal() {
// TODO Auto-generated method stub
// is connected,so do something
Toast.makeText(this, "网络正常,正常显示信息", Toast.LENGTH_SHORT).show();
}
}
Presenter连接了Model和View,代码如下:
public class Presenter {
private Activity activity;
private IMainView mainView;
private INetworkStatus networkStatus;
public Presenter(Activity activity) {
this.activity = activity;
mainView = (IMainView) activity;
networkStatus = new NetworkStatus();
}
/** 检查网络状态 */
public void checkNetworkStatus() {
try {
mainView.showProgress();
// 这里为了显示5s的进度条,添加了线程操作
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(5 * 1000); // 延迟,显示进度条
activity.runOnUiThread(new Runnable() {
public void run() {
if (networkStatus.isOnline(activity)) {
mainView.showDataNormal();
} else {
mainView.showNetworkError();
}
mainView.hideProgress();
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}).start();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
另外,由于使用的网络检查,需要添加Android网络状态权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
可以看到,MVP将Activity里复杂的逻辑处理全部放到Model,通过Presenter间接访问数据,并将数据处理结果通过View的接口来显示。
demo下载地址