MVC浅析(实际上应该是MVP,有时间再更新该博客)
16lz
2021-01-25
以Android中登录过程为例简单说明,其他应用场景同理。
定义接口:
Model层:IModelLogin.java
public interface IModelLogin { /** * 开始登录请求 * @param username * @param password */ abstract void iStartLogin(String username, String password);}
View层:IViewLogin.java
public interface IViewLogin { /** * 显示进度 * @param isProgress */ abstract void iShowProgress(boolean isProgress); /** * 错误提示 * @param object */ abstract void iErrorPrompt(Object object); /** * 进入到目标页面 */ abstract void iSwitchToTargetPage();}
Control层:ICtrlLogin.java
public interface ICtrlLogin { /** * 请求登录 * @param username * @param password */ abstract void iLogin(String username, String password); /** * 登录成功 * @param bean */ abstract void iLoginSuccess(UserInfo bean); /** * 登录失败 * @param message */ abstract void iLoginFailure(String message);}
至此整个登录过程的业务逻辑就已经梳理完毕了,过程为:页面点击登录按钮后,调用控制层接口iLogin,在iLogin中调用显示层接口iShowProgress显示进度条、并调用业务层的网络请求接口iStartLogin请求数据并解析,1.如果iStartLogin请求并解析登录成功则在iStartLogin中调用控制层接口iLoginSuccess,在iLoginSuccess中做相应处理并调用显示层接口iSwitchToTargetPage;2.如果业务层接口iStartLogin请求或解析登录失败则调用控制层接口iLoginFailure,在iLoginFailure中调用显示层接口iErrorPrompt。
下面贴出各层接口的实现类:
Model层:ModelLoginIpm.java
public class ModelLoginImp implements IModelLogin, INetResultListener { private static final String HTTP_LOGIN_TAG = "HTTP_LOGIN_TAG"; private static final String HTTP_LOGIN_METHOD = "/api/app/applogin"; private ICtrlLogin mPresent = null; public ModelLoginImp(ICtrlLogin present) { this.mPresent = present; } @Override public void iStartLogin(String username, String password) { NetRequest request = NetRequest.obtain(); request.setRequestMethod(RequestMethod.Post); request.setTag(HTTP_LOGIN_TAG); request.setClazz(HttpParser.class); request.setBaseUrl(ConstantValue.PUBLIC_NET_ADDRESS); // getRequestHeader(request, "", "", "", ""); // 交易服务代码(目标系统提供的URL地址) //request.addHeaderParam(); // 接口请求信息 request.setMethodUrl(HTTP_LOGIN_METHOD); request.addQueryParam("account", username); request.addQueryParam("password", password); request.setINetResultListener(this); request.doRequestAsyn(); } @SuppressWarnings("rawtypes") @Override public void iResultSuccess(NetResponse response, String tag) { try{ if(response!=null){ if(response.getResult()!=null &&response.getResult() instanceof HttpParser){ String data = ((HttpParser)response.getResult()).iParser(); mPresent.iLoginSuccess((UserInfo)JsonUtil.getClazzByGson(data, UserInfo.class)); } } }catch(NetException ex){ iResultFailure(ex,tag); }catch(Exception ex){ iResultFailure(new NetException(ex.getMessage(),""),tag); } } @Override public void iResultFailure(NetException ex, String tag) { mPresent.iLoginFailure(ex.getMsgInfo()); } @Override public void iResultStart(String tag) { }}
以上代码中使用了封装在自己写的框架中的网络请求和解析的方法,在此不便贴出来,请求和解析的方法原理都一样,网络上很多。
View层:LoginActivity.java
@ActivityFinder(R.layout.activity_login)public class LoginActivity extends BaseBackTitleActivity implements IViewLogin{ @ViewFinder(R.id.et_username) private EditText et_username; @ViewFinder(R.id.et_password) private EditText et_password; @ViewFinder(R.id.btn_login) private Button btn_login; /** * Loading window */ private ProgressDialog mProgressDialog = null; /** * ctrl层接口实现 */ private ICtrlLogin mPresent = null; public LoginActivity(){ mPresent = new CtrlLoginImp(this); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initView(); } /** * 初始化界面 */ private void initView(){ initTitle(R.string.text_login); btn_login.setOnClickListener(this); } @Override public void iShowProgress(boolean bRet) { if (mProgressDialog == null) { mProgressDialog = new ProgressDialog(this); } if (bRet) { mProgressDialog.show(); } else { mProgressDialog.dismiss(); } } @Override public void iErrorPrompt(Object object) { if(object !=null){ if(object instanceof Integer){ ToastTools.showToast((Integer)object); }else if(object instanceof String){ ToastTools.showToast((String)object); } } } @Override public void iSwitchToTargetPage() { this.finish(); } public void onClick(View arg0) { super.onClick(arg0); switch(arg0.getId()){ case R.id.btn_login: mPresent.iLogin(et_username.getText().toString(), et_password.getText().toString()); break; } }}
Control层:CtrlLoginImp.java
public class CtrlLoginImp implements ICtrlLogin { /** * Model层接口 */ IModelLogin mMode; /** * View 层接口 */ IViewLogin mView; /** * 用户名 */ private String mUsername; public CtrlLoginImp(IViewLogin mIViewLogin){ this.mView = mIViewLogin; this.mMode = new ModelLoginImp(this); } @Override public void iLogin(String username, String password) { if(checkInputFormat(username, password)){ mView.iShowProgress(true); mUsername = username; mMode.iStartLogin(username, password); } } /** * 数据本地检查 * @param username * @param password * @return */ private boolean checkInputFormat(String username, String password){ if(StringUtil.isBlank(username)){ mView.iErrorPrompt(R.string.warning_empty_username); return false; } if(PattenUtil.isCompanyNum(username)){ mView.iErrorPrompt(R.string.warning_wrong_username); return false; } if(StringUtil.isBlank(password)){ mView.iErrorPrompt(R.string.warning_empty_password); return false; } return true; } @Override public void iLoginSuccess(UserInfo bean) { mView.iShowProgress(false); if(bean!=null){ bean.username= mUsername; LoginManager.getInstance().onLogin(bean); mView.iSwitchToTargetPage(); } } @Override public void iLoginFailure(String message) { mView.iShowProgress(false); mView.iErrorPrompt(message); }}
接口设定了程序的逻辑结构,它就像是程序的说明书;接口实现中主要需要理解的是MCV三层如何协作。想必大家看了就会发现,按MVC模式编写的代码结构还是很清晰的。
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- Android(安卓)TelephonyManager类的使用
- 详解Android微信登录与分享
- Gallery练习(android)
- Android集成Zxing实现二维码扫描识别,过程、常见错误及修改
- Android各版本系统源代码下载
- Android(安卓)Watchdog 机制
- android 桌面小部件(App Widgets)如何显示自定义的view
- Android—fragment无法remove