热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

安卓/androidMVP开发模式的理解,以及代码讲解

安卓androidMVP开发模式的理解,以及代码讲解,Go语言社区,Golang程序员人脉社

MVP开发模式的理解,以及简单代码讲解

最近在网上看的MVP文章,根据自己的理解,特在此发篇文章记录下,这里我采用的是反向流程,文章如有需要优化之处,欢迎指导。也可加群进行讨论:855207609
在这里插入图片描述
在此啰嗦一句,首先看图,拿登录功能打比方说:
1、在View中调用P层(带输入数据)进行加载数据(此时还没请求接口)
2、在P中创建View和Model对象(此时的model层还没有创建,可以先省略)然后创建有参构造方法(View)
3、Model请求完接口后,将数据通过回调接口返回到P层,P在返回给VIew进行显示

项目结构图

在这里插入图片描述

  • MVP理解
    1.Model层:处理业务逻辑数据,如加载网络数据等(方法以及接口)
    2.View层:当P和V层执行完数据加载后进行回调给主线程进行显示(纯接口)
    3.Presenter层:是M和V的桥梁,是去小树林的必经之路。将View传递的请求数据传递给Model进行使用,当M请求完接口后,通过回调接口返回给P,此时P层通过已实例化的View将数据射入显示回调方法中进行UI显示。
View层

这里我把弹框抽离出来—使之公用;当然你也可以写在对应View层
作用:在主线程中进行implement此两个View用于最后的数据回调显示

public interface DialogView {
    /**
     * 显示弹框
     * @param message
     */
    void showDialog(String message);
    /**
     * 关闭弹框
     */
    void dismissDialog();
}

public interface LoginView {
    /**
     * 回调数据
     * @param result
     */
    void showData(String result);

//    /**
//     * 显示弹框
//     * @param message
//     */
//    void showDialog(String message);
//    /**
//     * 关闭弹框
//     */
//    void dismissDialog();
}
View层-Activity主线程调用:

首先实现View回调方法,然后调用P层方法,此时P层还没有创建

public class Login extends AppCompatActivity implements DialogView, LoginView {

    @BindView(R.id.et_Log_UserName)
    AutoCompleteTextView etLogUserName;
    @BindView(R.id.et_Log_PassWord)
    EditText etLogPassWord;
    @BindView(R.id.bt_Loading)
    Button btLoading;
    @BindView(R.id.email_login_form)
    LinearLayout emailLoginForm;
    private ProgressDialog mProgressDialog;

    private Handler mHandler;
    private Context mContext;
    private LoginPresenter loginPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        init();
        MyClick();

    }
    private void init(){
        mContext=Login.this;
        if (loginPresenter==null){
            loginPresenter=new LoginPresenter(this,this);
        }
        mHandler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what){
                    case 1:
                        Intent intent=new Intent(Login.this,Menu.class);
                        intent.putExtra("result",msg.obj.toString());
                        startActivityForResult(intent,1);
                        break;
                    default:
                            break;
                }
            }
        };

    }
    private void MyClick(){
        btLoading.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loginPresenter.reqLogin("test","123");
            }
        });
    }


    @Override
    public void showData(String result) {
//        Looper.prepare();
//        Toast.makeText(mContext, result+"", Toast.LENGTH_SHORT).show();
//        Looper.loop();
        Message msg=new Message();
        msg.what=1;
        msg.obj=result;
        mHandler.sendMessage(msg);

    }

    @Override
    public void showDialog(String message) {
        if (mProgressDialog==null){
            mProgressDialog=new ProgressDialog(Login.this);
        }
        mProgressDialog.setMessage(message);
        mProgressDialog.show();
    }

    @Override
    public void dismissDialog() {
        mProgressDialog.dismiss();
    }

}

Presenter层:

首先implement《P层》以及LoginModel对象等(此时还没有创建,所以我们要先去创建接口,然后在此实现其方法)》

public class LoginPresenter implements LoginIPresenter{
    private DialogView mDialog;
    private LoginView mLoginView;
    private LoginModel loginModel;
    public LoginPresenter(DialogView mDialog,LoginView mLoginView){
        this.mDialog=mDialog;
        this.mLoginView=mLoginView;
        if (loginModel==null){
            loginModel=new LoginModel();
        }
    }

//此处省略一些代码,内容请往下看
}


public interface LoginIPresenter {
    void reqLogin(String userName,String passWord);
}
Model层:

reqLogin方法中的LoginModel.LoginCallBack参数,可以先写上。此处是用于当请求完接口时直接回调给P层(如果有疑问,可以往下看,到P层可以看到请求方法中实现了一个 回调参数)

public interface LoginMode {
    void reqLogin(String userName, String passWord, LoginModel.LoginCallBack callBack);
}
Model层:

此时reqLogin方法中的参数添加了成功或失败回调接口,然后整体看一下是不是感觉,就像以前写在activity中的请求方法

public class LoginModel implements LoginMode{
    public LoginView loginView;
    @Override
    public void reqLogin(String userName, String passWord, final LoginCallBack callBack) {
        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int code=0;
                //请求接口
                //并返回数据,然后返回给view
                if (code==0){
                    callBack.onSuccess("登录成功");
                }else {
                    callBack.onError("登录失败,用户名或密码错误");
                }
            }
        }.start();
    }
	//这里的接口可以单独抽离出来,这里我就不抽离了
    public interface LoginCallBack{
        void onSuccess(String result);
        void onError(String error);
    }
}

Presenter层:

当P接口和M层创建完成后,创建弹框DialogView,登录LoginView,和登录LoginModel对象,然后创建有参构造并实例化View和Model并实例化,实现其方法

public class LoginPresenter implements LoginIPresenter{
    private DialogView mDialog;
    private LoginView mLoginView;
    private LoginModel loginModel;
    public LoginPresenter(DialogView mDialog,LoginView mLoginView){
        this.mDialog=mDialog;
        this.mLoginView=mLoginView;
        if (loginModel==null){
            loginModel=new LoginModel();
        }
    }

    @Override
    public void reqLogin(String userName, String passWord) {
        mDialog.showDialog("正在登陆中...");
        loginModel.reqLogin(userName, passWord, new LoginModel.LoginCallBack() {
            /**
             * 成功回调数据
             * @param result
             */
            @Override
            public void onSuccess(String result) {
                mDialog.dismissDialog();
                mLoginView.showData(result);
            }

            //失败回调原因
            @Override
            public void onError(String error) {
                mDialog.dismissDialog();
                mLoginView.showData(error);
            }
        });
    }
}

推荐文章:https://blog.csdn.net/limonzet/article/details/53328315
源码Git___Demo------>>>>>>diudiudiu


推荐阅读
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 实验九:使用SharedPreferences存储简单数据
    本实验旨在帮助学生理解和掌握使用SharedPreferences存储和读取简单数据的方法,包括程序参数和用户选项。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 在Django中提交表单时遇到值错误问题如何解决?
    在Django项目中,当用户提交包含多个选择目标的表单时,可能会遇到值错误问题。本文将探讨如何通过优化表单处理逻辑和验证机制来有效解决这一问题,确保表单数据的准确性和完整性。 ... [详细]
  • 作为软件工程专业的学生,我深知课堂上教师讲解速度之快,很多时候需要课后自行消化和巩固。因此,撰写这篇Java Web开发入门教程,旨在帮助初学者更好地理解和掌握基础知识。通过详细记录学习过程,希望能为更多像我一样在基础方面还有待提升的学员提供有益的参考。 ... [详细]
  • Vue ElementUI 实现邮箱地址自动补全功能详解 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • POJ 2482 星空中的星星:利用线段树与扫描线算法解决
    在《POJ 2482 星空中的星星》问题中,通过运用线段树和扫描线算法,可以高效地解决星星在窗口内的计数问题。该方法不仅能够快速处理大规模数据,还能确保时间复杂度的最优性,适用于各种复杂的星空模拟场景。 ... [详细]
  • 本文详细探讨了使用纯JavaScript开发经典贪吃蛇游戏的技术细节和实现方法。通过具体的代码示例,深入解析了游戏逻辑、动画效果及用户交互的实现过程,为开发者提供了宝贵的参考和实践经验。 ... [详细]
  • Java环境中Selenium Chrome驱动在大规模Web应用扩展时的性能限制分析 ... [详细]
author-avatar
chunhuai
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有