Android(Kotlin)框架MVP的简单实现

1.我们通常所说的MVP是什么?

M(Model)负责数据的请求,解析,过滤等数据操作。
V(View)负责处理UI,通常以Activity Fragment的形式出现。
P(Presenter)View Model中间件,交互的桥梁。

2.MVP的优点

分离了UI逻辑和业务逻辑,降低了耦合。
Activity只处理UI相关操作,代码变得更加简洁。
UI逻辑和业务逻辑抽象到接口中,方便阅读及维护。
把业务逻辑抽到Presenter中去,避免复杂业务逻辑造成的内存泄漏。

3.Base基础类

BaseView

/**
* Description:View的基类
*
* 负责处理UI,通常以Activity Fragment的形式出现。
*
* Time:2021/8/8-16:13
* Author:我叫PlusPlus
*/
interface BaseView {
/**
    * 结束当前Activity等
    */
    fun finish()
}

BasePresenter

/**
 * Description: Presenter的基类
 *
 * View Model中间件,交互的桥梁。
 *
 * Time:2021/8/8-16:12
 * Author:我叫PlusPlus
 */
abstract class BasePresenter<V : BaseView> {

    private var v: V? = null

    fun getView(): V {
        return v!!
    }

    fun attachView(view: V?) {
        this.v = view
    }

    fun detachView() {
        v = null
    }
}

BaseActivity

/**
 * Description:Activity基类
 *
 * Time:2021/8/8-16:12
 * Author:我叫PlusPlus
 */
abstract class BaseActivity<V : BaseView, P : BasePresenter<V>> : Activity() {
    /**
     * 定义泛型 View
     */
    private var view: V? = null

    /**
     * 定义泛型 Presenter
     */
    private var presenter: P ? = null

    /**
     * 可以被子类使用的Presenter
     */
    protected var currentPresenter :  P ? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //判断当前
        if (view == null) {
            view = createView()
        }
        if (presenter == null) {
            presenter = createPresenter()
        }
        //绑定view
        presenter?.attachView(view)
        currentPresenter = presenter
    }

    override fun onDestroy() {
        super.onDestroy()
        //剥离view
        presenter?.detachView()
    }

    /**
     * 创建View的抽象方法
     */
    abstract fun createView(): V
    /**
     * 创建Presenter的抽象方法
     */
    abstract fun createPresenter(): P
}

4.实现类,就以登录(Login)为例

LoginActivity

/**
 * Description:登录
 *
 * Time:2021/8/8-16:15
 * Author:我叫PlusPlus
 */
class LoginActivity : BaseActivity<LoginView, LoginPresenter>(), LoginView {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        httpBtn.setOnClickListener {
             currentPresenter?.sendHttpRequest()
        }
    }

    override fun createView(): LoginView {
       return this
    }

    override fun createPresenter(): LoginPresenter {
        return LoginPresenter()
    }

    override fun onLoginSuccess(message: String) {
        runOnUiThread {
            Toast.makeText(this, "请求成功 : $message",Toast.LENGTH_SHORT).show()
        }

    }

    override fun onLoginFailed(message: String) {
         runOnUiThread {
             Toast.makeText(this,"请求失败 : $message",Toast.LENGTH_SHORT).show()
         }
    }
}

LoginModel

/**
 * Description:登录Model
 *
 * 负责数据的请求,解析,过滤等数据操作
 * Time:2021/8/8-17:15
 * Author:我叫PlusPlus
 */
class LoginModel {
    /**
     * 请求成功监听
     */
    var httpSuccess: ((String) -> Unit)? = null

    /**
     * 请求失败监听
     */
    var httpFailed: ((String) -> Unit)? = null

    fun sendHttpRequest(request: String) {
        val okHttpClient: OkHttpClient = OkHttpClient()
        val httpRequest = Request.Builder()
            .url(request) //添加的url
            .get() // get请求
            .build()
        val call: Call = okHttpClient.newCall(httpRequest)
        call.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                httpFailed?.invoke(e.message.toString())
            }

            override fun onResponse(call: Call, response: Response) {
                httpSuccess?.invoke(response.body().toString())
            }
        })
    }
}

LoginPresenter

/**
 * Description:登录的Presenter
 *
 * Time:2021/8/8-16:19
 * Author:我叫PlusPlus
 */
class LoginPresenter : BasePresenter<LoginView>() {

    /**
     * 懒加载 LoginModel
     */
    private val loginModel by lazy {
        LoginModel()
    }

    fun sendHttpRequest() {
        //loginModel回调到当前Presenter,Presenter在回调到Activity
        loginModel.httpSuccess = {
            getView().onLoginSuccess(it)
        }
        loginModel.httpFailed = {
           getView().onLoginFailed(it)
        }
        loginModel.sendHttpRequest("http://wwww.baidu.com")
    }
}

LoginView

/**
 * Description:登录View
 *
 * Time:2021/8/8-16:17
 * Author:我叫PlusPlus
 */
interface LoginView : BaseView {
    /**
     * 登录成功回调
     */
    fun onLoginSuccess(message: String)
    /**
     * 登录失败回调
     */
    fun onLoginFailed(message: String)
}

总结

当前MVP只是将最基本的框架和基类搭建出来,可以根据自己的项目的需要做对应的修改。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最近稍微了解了下MVP架构模式,这篇文章写得不错,转过来mark下:原博客原地址:http://www.jians...
    Stan_Z阅读 1,230评论 0 8
  • MVP介绍: View 对应于Activity,负责View的绘制以及与用户交互 Model 依然是业务逻辑和实体...
    LiuZhanYue阅读 522评论 0 0
  • 一个好的好的设计模式可以帮我们很好的管理我们的代码,也会方便于我们的后期的扩展。特别是针对我们这样的新手,学好一个...
    JokerHerry阅读 563评论 0 0
  • 出处http://blog.csdn.net/self_study 目录(?)[+] 面试的时候被问到这个问题,用...
    岁月静好浅笑安然阅读 1,615评论 0 1
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,607评论 28 53