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的主要内容,如果未能解决你的问题,请参考以下文章