当前位置: 首页 > news >正文

Android 之 MVP架构

一、MVP架构分层与职责

层​​职责​​关键接口/类​
​Model​数据处理(网络请求、本地验证)UserRepository
​View​UI展示(Activity/Fragment),实现View接口,被动响应Presenter指令LoginContract.View
​Presenter​业务逻辑协调:接收View事件 → 调用Model → 处理结果 → 更新ViewLoginContract.Presenter

二、项目结构与包组织 

├── contract
│   └── LoginContract.java       // 定义View和Presenter接口
├── model
│   ├── UserRepository.java      // 数据操作实现
│   └── OnLoginListener.java     // 登录回调接口
├── presenter
│   └── LoginPresenter.java      // 业务逻辑实现
└── view
└── LoginActivity.java       // 实现View接口,处理UI

三、详细代码实现

1. ​​Contract接口(contract/LoginContract.java)
public interface LoginContract {interface View {void showLoading();void hideLoading();void showUsernameError(String error);void showPasswordError(String error);void onLoginSuccess();void onLoginFailure(String error);}interface Presenter {void attachView(View view);void detachView();void login(String username, String password);}
}

作用​​:统一管理View和Presenter的接口,避免类膨胀

2. ​​Model层(model/UserRepository.java)​
public class UserRepository {// 模拟网络请求登录public void login(String username, String password, OnLoginListener listener) {// 实际开发中替换为Retrofit/Volley请求if ("admin".equals(username) && "123456".equals(password)) {listener.onSuccess();} else {listener.onFailure("用户名或密码错误");}}public interface OnLoginListener {void onSuccess();void onFailure(String errorMsg);}
}

​职责​​:

  • 数据验证、网络请求、数据库操作
  • 通过回调接口OnLoginListener返回结果(避免直接依赖Presenter)
3. ​​Presenter层(presenter/LoginPresenter.java)
public class LoginPresenter implements LoginContract.Presenter {private LoginContract.View view;private UserRepository userRepository;public LoginPresenter() {userRepository = new UserRepository();}@Overridepublic void attachView(LoginContract.View view) {this.view = view;}@Overridepublic void detachView() {view = null; // 防止内存泄漏}@Overridepublic void login(String username, String password) {if (view == null) return;// 本地校验if (TextUtils.isEmpty(username)) {view.showUsernameError("用户名不能为空");return;}if (TextUtils.isEmpty(password)) {view.showPasswordError("密码不能为空");return;}view.showLoading();userRepository.login(username, password, new UserRepository.OnLoginListener() {@Overridepublic void onSuccess() {if (view != null) {view.hideLoading();view.onLoginSuccess();}}@Overridepublic void onFailure(String errorMsg) {if (view != null) {view.hideLoading();view.onLoginFailure(errorMsg);}}});}
}

关键逻辑​​:

  • 持有View的弱引用(通过attachView/detachView管理)
  • 本地验证 → 调用Model → 处理回调 → 更新View。
4. ​​View层(view/LoginActivity.java)
public class LoginActivity extends AppCompatActivity implements LoginContract.View {private EditText etUsername, etPassword;private Button btnLogin;private ProgressBar progressBar;private LoginPresenter presenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);etUsername = findViewById(R.id.et_username);etPassword = findViewById(R.id.et_password);btnLogin = findViewById(R.id.btn_login);progressBar = findViewById(R.id.progress_bar);presenter = new LoginPresenter();presenter.attachView(this);btnLogin.setOnClickListener(v -> {String username = etUsername.getText().toString().trim();String password = etPassword.getText().toString().trim();presenter.login(username, password);});}@Overrideprotected void onDestroy() {super.onDestroy();presenter.detachView(); // 解绑View,避免内存泄漏}// 实现View接口方法@Overridepublic void showLoading() {progressBar.setVisibility(View.VISIBLE);}@Overridepublic void hideLoading() {progressBar.setVisibility(View.GONE);}@Overridepublic void showUsernameError(String error) {etUsername.setError(error);}@Overridepublic void showPasswordError(String error) {etPassword.setError(error);}@Overridepublic void onLoginSuccess() {Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();startActivity(new Intent(this, HomeActivity.class));finish();}@Overridepublic void onLoginFailure(String error) {Toast.makeText(this, error, Toast.LENGTH_SHORT).show();}
}

四、总结:MVP vs MVC 优势

方面​​MVC​​MVP​​(本方案)
Activity职责同时处理UI和逻辑,臃肿仅处理UI,逻辑分离到Presenter
可测试性难(依赖Android组件)易(Presenter纯Java,可Mock测试)
耦合度View与Model直接交互View与Model完全解耦
内存泄漏风险高(异步回调持有Activity引用)低(通过detachView()主动解绑)
http://www.dtcms.com/a/313710.html

相关文章:

  • python---可变对象、不可变对象
  • SpringBoot学习总结
  • 在不可更改系统上构建数据响应机制的可选策略
  • 彻底屏蔽夸克浏览器更新
  • ORA-12514:TNS: 监听程序当前无法识别连接描述符中请求的服务
  • 【Spring】Bean的生命周期,部分源码解释
  • 【高等数学】第七章 微分方程——第九节 欧拉方程
  • Java基础:代码块/内部类/Lambda函数/常用API/GUI编程
  • LeetCode - 合并两个有序链表 / 删除链表的倒数第 N 个结点
  • 三角洲行动ACE反作弊VT-d报错?CPU虚拟化如何开启!
  • MySQL架构全面理解
  • 克罗均线策略思路
  • 无刷电机母线电容计算
  • SpringBoot AI自动化测试实战案例
  • 大模型能力测评(提示词请帮我把这个项目改写成为python项目)
  • 译|数据驱动智慧供应链的构成要素与关联思考
  • 死锁深度解析:原理、检测与解决之道
  • C++ <type_traits> 应用详解
  • 志邦家居PMO负责人李蓉蓉受邀为PMO大会主持人
  • 【深度学习新浪潮】谷歌新推出的AlphaEarth是款什么产品?
  • ZStack Cloud 5.3.40正式发布
  • 《测试驱动的React开发:从单元验证到集成协同的深度实践》
  • JAVA中的String类方法介绍
  • 【Bluetooth】【Transport层篇】第三章 基础的串口(UART)通信
  • 智能图书馆管理系统开发实战系列(六):Google Test单元测试实践
  • SAP 服务号传输(同环境的不同客户端SCC1,跨环境的STMS)
  • 一个网页的加载过程详解
  • lua中 list.last = last 和list[last]=value区别
  • C语言实现猜数字游戏
  • 多模态大模型综述:BLIP-2详解(第二篇)