Android Mvp架构的小demo

Posted lbj23vs6

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Mvp架构的小demo相关的知识,希望对你有一定的参考价值。

文章目录

前言

MVP模式是MVC模式在android上的一种变体,要介绍MVP就得先介绍MVC。在MVC模式中,Activity应该是属于View这一层。而实质上,它既承担了View,同时也包含一些Controller的东西在里面。这对于开发与维护来说不太友好,耦合度大高了。把Activity的View和Controller抽离出来就变成了View和Presenter,这就是MVP模式。

让我们来用mvp写一个登录界面

一、Model层

1.定义Model接口

public interface ILoginModel 
    void login(String account, String pwd, LoginListener listener);

2.实现ILoginModel ,用子线程睡眠3秒来模拟网络的请求过程

public class LoginModelImpl implements ILoginModel 
    private final Handler handler = new Handler(Looper.getMainLooper());

    @Override
    public void login(String account, String pwd, LoginListener listener) 
        new Thread(new Runnable() 
            @Override
            public void run() 
                try 
                    Thread.sleep(3_000);
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
                if (TextUtils.equals(account, "lbj") && TextUtils.equals(pwd, "123")) 
                    handler.post(new Runnable() 
                        @Override
                        public void run() 
                            listener.onSuccess();
                        
                    );
                 else 
                    handler.post(new Runnable() 
                        @Override
                        public void run() 
                            listener.onFailed();
                        
                    );
                
            
        ).start();
    

3.补充:Listener的定义

public interface LoginListener 
    void onSuccess();

    void onFailed();

二、Present 层

1.Presenter接口

代码如下(示例):

public interface ILoginPresenter 
    void doLogin(String account,String pwd);

2.实现Presenter接口

public class LoginPresenterImpl implements ILoginPresenter 

    private ILoginModel model;//持有model,请求数据
    private ILoginView view;//持有view,操控界面的行为

    public LoginPresenterImpl(ILoginView loginView) 
        model = new LoginModelImpl();
        view = loginView;
    

    @Override
    public void doLogin(String account, String pwd) 
        view.showPb();
        model.login(account, pwd, new LoginListener() 
            @Override
            public void onSuccess() 
                view.hidePb();
                view.toast("登录成功!!!");
            

            @Override
            public void onFailed() 
                view.hidePb();
                view.toast("登录失败!!!");
            
        );
    

三、View 层

1、IView接口,抽象view的行为

public interface ILoginView 
    void showPb();//展示进度条

    void hidePb();//隐藏进度条

    void toast(String content);

2、Activity 去实现IView接口

public class MainActivity extends AppCompatActivity implements ILoginView 

    private EditText etAccount;
    private Button btnLogin;
    private ProgressBar pbLogin;
    private EditText etPwd;
    private LoginPresenterImpl presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new LoginPresenterImpl(this);
        pbLogin = findViewById(R.id.pb_login);
        btnLogin = findViewById(R.id.btn_login);
        etAccount = findViewById(R.id.et_account);
        etPwd = findViewById(R.id.et_pwd);
        btnLogin.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                presenter.doLogin(etAccount.getText().toString(), etPwd.getText().toString());
            
        );
    

    @Override
    public void showPb() 
        pbLogin.setVisibility(View.VISIBLE);
    

    @Override
    public void hidePb() 
        pbLogin.setVisibility(View.INVISIBLE);
    

    @Override
    public void toast(String content) 
        Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
    

补充:xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".view.MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="账号"
        android:textSize="34sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/et_account"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/textView"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="36dp"
        android:text="密码"
        android:textSize="34sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <EditText
        android:id="@+id/et_pwd"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="39dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/textView2"
        app:layout_constraintTop_toBottomOf="@+id/et_account" />

    <Button
        android:id="@+id/btn_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="59dp"
        android:text="登录"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_pwd" />

    <ProgressBar
        android:id="@+id/pb_login"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:visibility="invisible"
        app:layout_constraintBottom_toTopOf="@+id/btn_login"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_pwd" />
</androidx.constraintlayout.widget.ConstraintLayout>

总结

枯燥的看mvp架构难以理解,建议新手敲一下这个登录界面,使用mvp架构,这样可以大致建立一个对mvp架构的初步理解,后续就可以在项目中使用也可以与他人交流。

android-MVP+RxBus开发框架Demo

引子

总算有时间总结一下MVP代码框架,顺便把最近看到的消息总线RxBus 也整合到一起 。

本文内容主要是 本人对MVP代码框架的理解,以及 一种比较好理解的自定义RxBus的写法。

最后将会奉上Demo的Github地址;

 

MVP代码架构


Model层,纯粹的数据层,核心代码是 数据的获取和变更(即增删改查),数据来源可以是网络请求,本地文件(xml,json),本地数据库(sqlite);通常,数据变更或获取逻辑 执行完毕之后,会 通过返回值,或者 实参赋值的方式告知P层;(纯java)
View层,纯粹的视图UI层,核心代码,是 界面组件的初始化,UI变更的函数等UI逻辑,不涉及任何的业务逻辑;(java+layout.xml)
Presenter层,纯粹的业务逻辑层,没有任何UI变更代码,没有任何 数据获取或变更的代码,但是,可以调用UI变更的函数,可以调用数据获取或变更的函数。(纯java)

 

技术分享图片

 

RxBus消息总线

由于近期是第一次接触,虽然可以将RxBus应用到我写的框架中,但是仍然理解不够深刻。

所以原理方面就不在这里细说了,下面列出RxBus相关的基本概念;

ReactiveX:专注于异步编程和控制可观察数据和事件流的API,它组合了观察者模式,迭代器模式,函数式编程的优秀思想;

RxJava: ReactiveX的java实现;

RxJava作用 :异步编程,可以很方便解决任何android组件之间的消息传递,比 startActivityForResult的方式更好。(但是理论上不仅仅是组件之间,任意两个对象之间都可以用这种方式传递消息)

核心类: Observable(观察者) Subscriber(订阅者);

Observable :  发出数据流或者事件的类,

Subscriber :  对这些发出的 items (数据流或者事件)进行处理(采取行动)的类。

RxBus: 我们用自己的代码实现的 异步编程消息总线;(所以每个人写的都可能不同);

 

 

下面说一下我自己写的RxBus库里面用到的技术点:

1-线程安全的单例模式(同步代码块+多重判空+volatile关键字); 消息总线类,在项目中只能存在一个,才能保证消息的统一分发

2-线程安全的CopyOnWriteArraySet集合类

3-注解函数+反射调用,实现“订阅者”执行函数的自动调用

 

Demo整体代码框架一览

技术分享图片

 

 按照标记来:

1-数据层Model全部代码

2-逻辑层Presenter全部代码

3-视图层View的java代码

4-视图层View的xml配置

5-将消息总线 封装到一个Android-library中

6-注解接口,用于让RxBus识别出回调方法并且执行

7-反射调用的辅助类,由于是完全独立的功能,并没有和RxBus形成绑定关系,所以单独提出来

8-RxBus的接口类

9-RxBus实现类

 

然后MVP层的详细结构:

技术分享图片

1-数据Model层的接口规范,使用了泛型接口,方便对接不同的业务

2-业务Presenter层抽象类,使用了泛型接口,并且将公共的函数提取到了抽象类中,最大程度精简 业务代码;

3-视图View层接口规范,要求所有 需要对接P层的组件都要实现这个IView接口。

4-业务1,以学校为案例,这个leader是领导;

5-业务2,学生

6-业务3,老师

7-P层实现类

8-业务1的Fragment

9-业务2的Fragment

10-业务3的Activity

 

 最终效果

技术分享图片

 

OK,任意组件之间的信息互通,用过这种方式,eazy。

 

Github地址

https://github.com/18598925736/MVP-RxBus

 

 

 

 

 

 

 




以上是关于Android Mvp架构的小demo的主要内容,如果未能解决你的问题,请参考以下文章

Android中的MVP架构初探

Android开发中的MVP架构

android MVP——mvp架构的应用和优化

Android官方MVP架构解读

Google 官方Android MVP架构实践

Android MVP架构分析