Android_MVP开发模式登录注册案例
来源:互联网 发布:程序员修炼之道 mobi 编辑:程序博客网 时间:2024/05/18 03:11
首先MVP 是从经典的MVC架构演变而来
系统C/S(Client/Server)三层架构模型:
1)视图层(View):一般采用XML文件对应用的界面进行描述,使用的时候可以直接引入,极为方便,可以的大大缩短开发时间,也可以使用JavaScript+HTML等的方式作为View层,当然这里需要进行Java和JavaScript之间的通信,幸运的是,Android提供了非常方便的通信实现。业务逻辑层(BLL):它的关注点主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计,也即是说它是与系统所应对的领域(Domain)逻辑有关,很多时候,也将业务逻辑层称为领域层。
2)控制层(Controller):Android的控制层的重任通常落在了众多的Acitvity的肩上,这句话也就暗含了不要在Acitivity中写代码,要通过Activity交割Model业务逻辑层处理。
3)模型层(Model):对数据库的操作、以及其他和数据有关的的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。就是应用程序中二进制的数据。
三层结构架构三层间的交互及作用如下图所示:
在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。
在MVP里,Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。而且,Presenter与具体的View是没有直接关联的,而是通过接口进行交互,从而使得在变更View时候可以保持Presenter的不变,可以多次复用。
在MVP里,应用程序的逻辑主要在Presenter来实现,其中的View是很薄的一层,只应该有简单的Set/Get的方法,用户输入和设置界面显示的内容,除此就不应该有更多的内容,绝不容许直接访问Model。
MVP主要解决就是把逻辑层抽出来成P层,要是遇到需求逻辑上的更改就可以只需要修改P层了或者遇到逻辑上的大改我们可以直接重写一个P也可以,很多开发人员把所有的东西都写在了Activity/Fragment里面这样一来遇到频繁改需求或者逻辑越来越复杂的时候,Activity /Fragment里面就会出现过多的混杂逻辑导致出错,所以MVP模式对于APP来对控制逻辑和UI的解耦来说是一个不错的选择。
开始实例
一:布局
1:登录页面布局
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="activity.example.com.mvpframework.view.MainActivity"> <EditText android:id="@+id/ed_phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入手机号" android:layout_above="@+id/ed_pass" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginBottom="55dp" /> <EditText android:id="@+id/ed_pass" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入密码" android:layout_above="@+id/btn_login" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginBottom="94dp" /> <Button android:id="@+id/btn_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登录" android:layout_marginLeft="65dp" android:layout_marginStart="65dp" android:layout_alignBaseline="@+id/btn_regis" android:layout_alignBottom="@+id/btn_regis" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <Button android:id="@+id/btn_regis" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="注册" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginRight="43dp" android:layout_marginEnd="43dp" android:layout_marginBottom="130dp" /></RelativeLayout>2:注册页面布局
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="activity.example.com.mvpframework.view.RegisActivity"> <EditText android:id="@+id/ed_phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入手机号" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginTop="61dp" /> <EditText android:id="@+id/ed_pass" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入密码" android:layout_marginBottom="63dp" android:layout_above="@+id/btn_regis" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <Button android:id="@+id/btn_regis" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="注册" android:layout_marginBottom="169dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_marginLeft="130dp" android:layout_marginStart="130dp" /></RelativeLayout>
3:登录成功跳转的页面,在此就不写了
1:登录、注册 成功或失败的接口
public interface Login { void succeed(String data); void failed(String message);}
2:请求网络成功或失败的接口
public interface Http { void onSuccess(String data); void onFiled(String message);}
三:M(model)层,提供数据,单例模式
public class HttpUtils { private static volatile HttpUtils instance; private HttpUtils(){ } public static HttpUtils getInstance(){ if(instance==null){ synchronized (HttpUtils.class){ if(instance==null){ instance = new HttpUtils(); } } } return instance; } public void get(String url, Map<String, String> map, final Http http) { RequestParams params = new RequestParams(url); for (Map.Entry<String, String> entry : map.entrySet()) { params.addQueryStringParameter(entry.getKey(), entry.getValue()); } x.http().get(params, new Callback.CommonCallback<String>() { @Override public void onSuccess(String result) { http.onSuccess(result); } @Override public void onError(Throwable ex, boolean isOnCallback) { http.onFiled(ex.getMessage()); } @Override public void onCancelled(CancelledException cex) { } @Override public void onFinished() { } }); }}
四:P(Presenter)层,逻辑处理
public class LoginPresenter { private Login login; private Context context; // 提供初始化IView对象的一个方法 public LoginPresenter() { } public LoginPresenter(Login login,Context context) { this.login = login; this.context=context; } public boolean checkData(String phone,String pass) { if(TextUtils.isEmpty(phone)||TextUtils.isEmpty(pass)){ Toast.makeText(context,"用户名或密码不能为空",Toast.LENGTH_SHORT).show(); return false; } //验证是否为手机号的正则表达式 String regex = "^1[3|4|5|7|8]\\d{9}"; if(!Pattern.matches(regex,phone)){ Toast.makeText(context,"手机号格式不正确",Toast.LENGTH_SHORT).show(); return false; } if(pass.length()<6){ Toast.makeText(context,"密码长度需要大于6位",Toast.LENGTH_SHORT).show(); return false; } return true; } public void login(String url,String username, String password) { Map<String, String> map = new HashMap<>(); map.put("mobile", username); map.put("password", password); HttpUtils.getInstance().get(url, map, new Http() { @Override public void onSuccess(String data) { //解析 Gson gson = new Gson(); DataBean dataBean = gson.fromJson(data, DataBean.class); //获取code值,返回0为成功,1为失败 if(dataBean.getCode().trim().equals("0")){ login.succeed(data); Toast.makeText(context,dataBean.getMsg(),Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context,dataBean.getMsg(),Toast.LENGTH_SHORT).show(); } } @Override public void onFiled(String message) { login.failed(message); } }); } //防止内存泄漏 public void detatch(){ if (login != null) { login = null; } }}
五:V(View)层,展示页面,不做逻辑处理
1:MainActivity登录页面
public class MainActivity extends AppCompatActivity implements Login,View.OnClickListener{ private EditText ed_phone; private EditText ed_pass; private Button btn_login; private Button btn_regis; private LoginPresenter presenter1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { //获取id ed_phone = (EditText)findViewById(R.id.ed_phone); ed_pass = (EditText)findViewById(R.id.ed_pass); btn_login = (Button)findViewById(R.id.btn_login); btn_regis = (Button)findViewById(R.id.btn_regis); //点击监听 btn_login.setOnClickListener(this); btn_regis.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.btn_login: String user = ed_phone.getText().toString().trim(); String pass = ed_pass.getText().toString().trim(); //实例化p层 presenter1 = new LoginPresenter(this,MainActivity.this); //效验输入的值是否符合格式 boolean b = presenter1.checkData(user, pass); if(b){ presenter1.login("http://120.27.23.105/user/login",user,pass); } break; case R.id.btn_regis: //跳到注册页面 startActivity(new Intent(MainActivity.this,RegisActivity.class)); break; } } @Override public void succeed(String data) { //登录成功跳到另一个页面 startActivity(new Intent(MainActivity.this,ShopActivity.class)); } @Override public void failed(String message) { //正常情况不会执行,只有请求网络失败的时候才会执行,这里的失败是指网页打不开的失败 Toast.makeText(MainActivity.this,"网络异常,登录失败",Toast.LENGTH_SHORT).show(); } //防止内存泄漏 @Override protected void onDestroy() { super.onDestroy(); if (presenter1 != null) { presenter1.detatch(); } }}2:注册页面
public class RegisActivity extends AppCompatActivity implements Login,View.OnClickListener{ private EditText ed_phone; private EditText ed_pass; private Button btn_regis; private LoginPresenter presenter1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_regis); ed_phone = (EditText)findViewById(R.id.ed_phone); ed_pass = (EditText)findViewById(R.id.ed_pass); btn_regis = (Button)findViewById(R.id.btn_regis); btn_regis.setOnClickListener(this); } @Override public void onClick(View view) { String user = ed_phone.getText().toString().trim(); String pass = ed_pass.getText().toString().trim(); presenter1 = new LoginPresenter(this,RegisActivity.this); boolean b = presenter1.checkData(user, pass); if(b){ presenter1.login("http://120.27.23.105/user/reg",user,pass); } } @Override public void succeed(String data) { finish(); } @Override public void failed(String message) { //正常情况不会执行,只有请求网络失败的时候才会执行,这里的失败是指网页打不开的失败 Toast.makeText(RegisActivity.this,"网络异常,注册失败",Toast.LENGTH_SHORT).show(); } //防止内存泄漏 @Override protected void onDestroy() { super.onDestroy(); if (presenter1 != null) { presenter1.detatch(); } }}
阅读全文
2 0
- Android_MVP开发模式登录注册案例
- Android_MVP模式Demo
- 用户注册登录案例
- 登录注册案例
- 用户登录注册案例
- android_MVPd登录注册案例
- 用户登录注册界面开发及用户信息管理案例详解
- JavaWeb_mvc案例_注册登录
- 用户登录注册案例分析
- 用户注册和登录案例
- 用户登录注册案例分析
- 登录注册案例(集合实现)
- 11 jstl标签 JSP开发模式 注册案例
- 登录注册mvp模式
- 基于Servlet+JSP+JavaBean开发模式的用户登录注册
- 基于Servlet+JSP+JavaBean开发模式的用户登录注册
- 基于Servlet+JSP+JavaBean开发模式的用户登录注册
- 基于Servlet+JSP+JavaBean开发模式的用户登录注册
- emmc-ufs-LPDDR 简介
- 博主最近学习
- EventBus简单传值
- 心得
- 利用Eclipse JDT ASTRewrite向java源码添加代码
- Android_MVP开发模式登录注册案例
- C++ 中,实现strcpy的
- 什么是比特币挖矿和区块链共识机制?
- 博客
- 逻辑卷管理
- EasyEDA 入坑
- 深度学习
- virtalbox Linux ubntu centos随笔
- android 开发坑点记录