MVP在Android中2种实现(1)

xiaoxiao2021-02-27  159

对此题目有兴趣的同学都是知道至少了解这个东西,在此我不准备讲太多的理论,因为互联网上对MVP的介绍铺天盖地了.例如这位同学的文章就很精彩 Android MVP 详解(上),本人只是介绍两种MVP在Android的实现方法。

第一种:MVP在Android中2种实现(1) 第二种: MVP在Android中2种实现(2)

第一种

众所周知,MVP全称 Model-View-Presenter Model:负责提供数据,转化为目标格式供上层接口调用 View:负责内容显示及操作指令下发 Presenter:负责协调View和Model

首先,由于大部分Android APP只是一个客户端,具体的业务逻辑几乎都在后台服务器,所以此处降低了Model的职责,将从后台获取数据写在了Presenter里面,特此说明。

本例以开发一个登陆功能来说明 具体实现思路如下: 我们知道要针对抽象编程,所以先设计接口:此处我们需要两个接口,第一个是业务逻辑接口表示登录这个操作,让presenter实现。第二个是View要实现的接口,表示View要针对登录这个操作返回的结果做出响应。

presenter实现的接口Login1Presenter

package com.ss007.androidmvpsample.mvp; /** * Copyright (C) 2017 * * * @author ben * @version 1.0 * @createDate 2017/7/5 10:30 * @description */ public interface Login1Presenter { void login(String userName,String passWord); }

View实现的接口Login1ActView

package com.ss007.androidmvpsample.mvp; /** * Copyright (C) 2017 * * * @author ben * @version 1.0 * @createDate 2017/7/5 10:29 * @description */ public interface Login1ActView { void loginSuccess(String responseStr); void loginFailed(String code,String errBody); }

Model

省略

View

View 自然就让我们的Activity来充当了,命名为Login1Act,样子如下图

负责参数输入,指令触发(登录),对处理结果及时作出响应

package com.ss007.androidmvpsample.mvp; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.ss007.androidmvpsample.BaseActivity; import com.ss007.androidmvpsample.R; public class Login1Act extends BaseActivity implements Login1ActView { private final static String TAG = Login1Act.class.getSimpleName(); private EditText userName, passWord; private Button btnLogin; private Login1Presenter mPresenter; private Activity mAct; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login1); mAct = this; userName = (EditText) findViewById(R.id.et_user_name); passWord = (EditText) findViewById(R.id.et_password); btnLogin = (Button) findViewById(R.id.btn_login); btnLogin.setOnClickListener(clickListener); mPresenter = new Login1PresenterImp(this); } @Override public void loginSuccess(String responseStr) { btnLogin.setText("Login"); Log.d(TAG, String.format("result: %s", responseStr)); Toast.makeText(mAct, "login success", Toast.LENGTH_SHORT).show(); } @Override public void loginFailed(String code, String errBody) { Log.d(TAG, String.format("error code:%s | error body: %s", code, errBody)); Toast.makeText(mAct, "login failed", Toast.LENGTH_SHORT).show(); } private View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_login: if (mPresenter != null) { btnLogin.setText("Loginning ..."); mPresenter.login(userName.getText().toString(), passWord.getText().toString()); } break; default: break; } } }; }

Presenter

负责向后台发起网络请求

package com.ss007.androidmvpsample.mvp; import android.os.Handler; /** * Copyright (C) 2017 * * * @author ben * @version 1.0 * @createDate 2017/7/5 10:30 * @description */ public class Login1PresenterImp implements Login1Presenter { private Login1ActView login1ActView; public Login1PresenterImp(Login1ActView login1ActView) { this.login1ActView=login1ActView; } @Override public void login(String userName, String passWord) { //模拟登录(Mock login) new Handler().postDelayed(new Runnable() { @Override public void run() { boolean isSuccess=true;//根据实际情况判断 if (login1ActView==null) return; if (isSuccess) { login1ActView.loginSuccess("the result get from your server"); } else { login1ActView.loginFailed("error code","error body"); } } }, 2000); } }

代码已经非常简单明了了,在此我做一点讲解: 第一步:根据业务需要定义两个接口,一个给Presenter实现,一个给View实现。 第二步:如果决定使用轻Model重Presenter的模式,那么Model基本就是一些JavaBean类,让View持有Presenter的引用(最好是以接口声明),那么在View中就可以调用Presenter里面的方法了,例如点击登录按钮,调用presenter里面的login()方法。 第三步:Presenter里面的方法执行后会有结果回来,那么View是要对这些结果做出响应的,例如登录后是成功了还是失败了呢?这就需要从Presenter里面调用View里面的方法将结果传过去。所以需要Presenter持有一个View的引用(最好是以接口声明)。

小结

这种方法的优点就是简单,但是有一个比较严重的问题就是在一定的情况下会造成内存泄漏。 例如这个登录页面没有一个不可取消的loading弹窗,那么用户就可以随时关闭登录页面,那么由于Presenter持有View的引用,而又当Presenter有未完成的操作不能被GC回收时,Activity也不能够释放,就会造成内存泄漏。

第二种方法将会讲解如何改进第一种方法,避免内存泄漏。

源码下载

转载请注明原文地址: https://www.6miu.com/read-16375.html

最新回复(0)