一、MVC基本概念
MVC(Model-View-Controller,模型-视图-控制器)模式在Android中曾经是比较流行的架构设计模式;使用MVC设计模式的好处UI界面与业务逻辑数据的分离,在修改或者优化界面及用户交互的同时,无需重新编写业务逻辑。Android中的MVC的角色如下:
- 模型层(Model):是用进行业务逻辑的处理,比如一些网络访问操作、数据库的操作等等,总之一些耗时操作的任务。
- 视图图(View):主要是处理数据显示的部分,在Android中xml布局就可以视为V层。
- 控制层(Controller):在Android中,Activity是处理用户交互问题,因此通常把Activity或者Fragment视为控制器,通过C层来操作M层获取数据,并把数据返回给V层显示。
二、MVC基本使用
项目目录结构分成了三个目录,分别是model、controller、listener,其中model目录下存放一些javabean类和业务数据获取接口及其实现类(网络访问);controller目录存放Activity或者Fragment;listener目录下是存放网络访问操作结果的回调接口,目的是将数据返回给View层显示。下面一个简单登录为例:
LoginListener接口:其实这个接口实现回调也相当于model层中一部分。
/**
* desc:登录回调监听
*/
public interface LoginListener<T> {
/*请求前一些准备,比如加载提示等待*/
void onStart_();
/*访问成功调用*/
void onSuccess(T t);
/*访问失败*/
void onFailed();
/*访问结束*/
void onFinish();
}
Model层:
/**
* desc: 用户信息实体类
*/
public class UserInfo {
private String userName;
private String sex;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
/**
* desc: login-Model
*/
public interface LoginModel<T>{
void getUserInfo(String userName, String pwd, LoginListener<T> listener);
}
/**
* desc:LoginModel的实现类,网络异步访问
*/
public class LoginModelImpl implements LoginModel<UserInfo>{
@Override
public void getUserInfo(String userName, String pwd, LoginListener<UserInfo> listener) {
UserInfo userInfo = new UserInfo();
userInfo.setUserName(userName);
//下面是模拟网络访问结果的调用
listener.onStart_();
if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(pwd)){
listener.onSuccess(userInfo);
}else {
listener.onFailed();
}
listener.onFinish();
}
}
View层:xml布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/et_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"/>
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPassword"/>
<Button
android:id="@+id/but_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"/>
</LinearLayout>
Controller层:
public class MainActivity extends AppCompatActivity implements LoginListener<UserInfo> {
private EditText mEtName;
private EditText mEtPassword;
private Button mButLogin;
private LoginModelImpl mLoginModel;
private ProgressDialog mProgressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEtName = findViewById(R.id.et_user_name);
mEtPassword = findViewById(R.id.et_password);
mButLogin = findViewById(R.id.but_login);
mLoginModel=new LoginModelImpl();
mButLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//登录
String userName = mEtName.getText().toString();
String pwd = mEtPassword.getText().toString();
mLoginModel.getUserInfo(userName,pwd,MainActivity.this);
}
});
}
@Override
public void onStart_() {
Log.d(TAG, "onStart_: ");
mProgressDialog=new ProgressDialog(this);
mProgressDialog.setTitle("请求中……");
mProgressDialog.show();
}
@Override
public void onSuccess(UserInfo userInfo) {
Log.d(TAG, "onSuccess: ");
mProgressDialog.dismiss();
Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed() {
Log.d(TAG, "onFailed: ");
Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();
}
@Override
public void onFinish() {
Log.d(TAG, "onFinish: ");
mProgressDialog.dismiss();
}
private static final String TAG = "MainActivity";
}
上面例子是MVC的简单运用,当你点击登录就是获取登录数据,通过modle层中的接口实现类(LoginModelImpl)来获取网络数据,并把数据返回View层显示交互,从上面例子可以看出,Controller控制器Activity一定程度上实现了视图UI层与数据Modle层的解耦,将View层和Modle
层进行了分离,但并不是十分完美,就是在Controller层Activity中同时存在布局视图初始化和业务逻辑操作响应,也就是View层初始化和Controller层同时绑定到同一类中。当业务越来越复杂时,Activity的职责会越来越多,代码会越来越浮肿,不利于后期的维护。
Android架构设计之MVP模式