飞道的博客

Kotlin+Retrofit+Okhttp+MVP架构的搭建以及示例代码

474人阅读  评论(0)

本文地址:https://blog.csdn.net/qq_40785165/article/details/113200783,转载需附上此地址

大家好,我是小黑,一个还没秃头的程序员~~~

最近是真的忙,忙到不想写博客,但是还是那句老话--既然选择了远方,便只顾风雨兼程。

今天的内容是Kotlin+Retorfit+Okhttp+MVP架构的搭建,由于Kotlin+Retrofit+Okhttp的搭建我之前的博客中已经有案例了,有需要的小伙伴可以跳转至文章地址查看,所以本文的重点在于MVP架构的代码介绍

本文章涉及的Demo地址:项目地址,里面有标题中涉及到的所有知识点,有需要的小伙伴可以去看看项目源码,Demo的功能为登录成功后可进行查看数据列表,也可退出登录,Demo的运行效果以及项目目录结构如下所示

我之前也有写过Kotlin+MVC的博客,感兴趣的小伙伴可以去文章地址查看原文

MVC中View层指的是xml代码或者Java代码写的自定义view,Control层指的是Activity/Fragment,View层可以直接与Model进行交互,更新UI的工作都是在Control层执行,但是MVP架构中View层指的就是Activity/Fragment,View层只能通过Presenter层和Model进行交互,或者说Presenter层是作为View与Model的桥梁,View层通过Presenter层调用Model层的接口进行数据处理,Model层执行结束将结果回调通知Presenter层,Presenter层通过回调通知View层进行UI更新,从代码而言,MVC更容易易懂,但是代码容易臃肿,MVP容易产生过多的类和接口,但是分工明确,易于拓展。以上是我个人的理解,若有不同见解,欢迎底下评论区多多指教!

正文开始,以下以效果中的登录功能为例(退出以及列表功能代码请阅读项目源码),接口调用wanandroid的开放Api

(一)View层代码

activity_login.xml


  
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width= "match_parent"
  4. android:layout_height= "match_parent"
  5. android:orientation= "vertical">
  6. <LinearLayout
  7. android:layout_width= "match_parent"
  8. android:layout_height= "wrap_content">
  9. <TextView
  10. android:layout_width= "wrap_content"
  11. android:layout_height= "wrap_content"
  12. android:text= "账号:" />
  13. <EditText
  14. android:id= "@+id/et_account"
  15. android:layout_width= "match_parent"
  16. android:layout_height= "wrap_content"
  17. android:hint= "请输入账号"
  18. android:inputType= "text"
  19. android:text= "" />
  20. </LinearLayout>
  21. <LinearLayout
  22. android:layout_width= "match_parent"
  23. android:layout_height= "wrap_content">
  24. <TextView
  25. android:layout_width= "wrap_content"
  26. android:layout_height= "wrap_content"
  27. android:text= "密码:" />
  28. <EditText
  29. android:id= "@+id/et_password"
  30. android:layout_width= "match_parent"
  31. android:layout_height= "wrap_content"
  32. android:hint= "请输入密码"
  33. android:inputType= "text"
  34. android:text= "" />
  35. </LinearLayout>
  36. <TextView
  37. android:id= "@+id/tv_login"
  38. android:layout_width= "@dimen/dp_40"
  39. android:layout_height= "@dimen/dp_40"
  40. android:layout_gravity= "center"
  41. android:layout_marginTop= "@dimen/dp_40"
  42. android:background= "#c0c0c0"
  43. android:gravity= "center"
  44. android:text= "登录"
  45. android:textColor= "#000" />
  46. </LinearLayout>

LoginActivity.kt代码如下,activity继承了LoginView接口,实现更新UI方法,易于通过Presenter与Model进行交互并接受回调


  
  1. class LoginActivity : AppCompatActivity(), LoginView {
  2. private val loginModel: LoginModel by lazy {
  3. LoginModel()
  4. }
  5. private val loginPresenterImpl: ILoginPresenter by lazy {
  6. LoginPresenterImpl( this, loginModel)
  7. }
  8. override fun onCreate(savedInstanceState: Bundle?) {
  9. super.onCreate(savedInstanceState)
  10. setContentView(R.layout.activity_login)
  11. initListener()
  12. }
  13. private fun initListener() {
  14. tv_login.setOnClickListener {
  15. loginPresenterImpl.login(et_account.text.toString(), et_password.text.toString())
  16. }
  17. }
  18. override fun showLoading() {
  19. Toast.makeText( this, "登录加载中", Toast.LENGTH_SHORT).show()
  20. }
  21. override fun hideLoading() {
  22. Toast.makeText( this, "登录加载结束", Toast.LENGTH_SHORT).show()
  23. }
  24. override fun loginSuccess() {
  25. Toast.makeText( this, "登录成功", Toast.LENGTH_SHORT).show()
  26. var intent = Intent( this, MainActivity:: class.java)
  27. startActivity(intent)
  28. finish()
  29. }
  30. override fun loginFail(msg: String?) {
  31. Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show()
  32. }
  33. }

LoginView.kt代码如下,定义了各种需要更新UI的函数,用于P层调用这些函数进行通知UI更新


  
  1. /**
  2. * 用来View层更新UI的接口
  3. */
  4. interface LoginView {
  5. /**
  6. * 显示加载中提示
  7. */
  8. fun showLoading()
  9. /**
  10. * 隐藏加载中提示
  11. */
  12. fun hideLoading()
  13. /**
  14. * 登陆成功的UI更新
  15. */
  16. fun loginSuccess()
  17. /**
  18. * 登录失败的UI更新
  19. */
  20. fun loginFail(msg: String?)
  21. }

(二)Presenter层代码

 

ILoginPresenter.kt代码如下,定义了Presenter层需要调用的方法,在该方法里进行逻辑处理或者调用Model,也方便拓展


  
  1. /**
  2. * P层作为view与model的媒介,需要的接口方法
  3. */
  4. interface ILoginPresenter {
  5. fun login(account: String, password: String)
  6. }

LoginPresenterImpl.kt代码如下,实现了ILoginPresenter中的接口方法,并实现Model层约定的回调方法,调用Model层进行数据处理,Presenter层作为中间件,所以需要持有View层与Model层的对象


  
  1. /**
  2. * 作为媒介联系view与model,view和model各司其职互不干扰,等待model返回回调,present再去通知view层进行UI更新
  3. */
  4. class LoginPresenterImpl(loginView: LoginView, iLoginModel: ILoginModel) : ILoginPresenter,
  5. LoginListener {
  6. private var loginView: LoginView? = null
  7. private var loginModel: ILoginModel? = null
  8. init {
  9. this.loginModel = iLoginModel
  10. this.loginView = loginView
  11. }
  12. override fun login(account: String, password: String) {
  13. loginView?.showLoading()
  14. loginModel?.login(account, password, this)
  15. }
  16. override fun loginSuccess() {
  17. loginView?.hideLoading()
  18. loginView?.loginSuccess()
  19. }
  20. override fun loginFail(msg: String?) {
  21. loginView?.hideLoading()
  22. loginView?.loginFail(msg)
  23. }
  24. }

(三)Model层代码

ILoginModel.kt代码如下,也是一个接口,定义数据处理函数名


  
  1. /**
  2. * 处理数据的接口方法
  3. */
  4. interface ILoginModel {
  5. fun login(account: String, password: String, loginListener: LoginListener)
  6. }

LoginModel.kt代码如下,实现接口函数,使用retrofit+okhttp进行登录请求,并且将结果通过回调通知Presenter层,retrofit代码这里就不贴出来了,可以前往项目地址查看项目源码


  
  1. class LoginModel : ILoginModel {
  2. override fun login(account: String, password: String, loginListener: LoginListener) {
  3. HttpHelper.getApi()?.login(account, password)
  4. ?.enqueue( object : SingleCallback<Result<UserBean>>() {
  5. override fun onSuccess(response: Result<UserBean>) {
  6. if ( "0".equals(response.errorCode)) {
  7. loginListener.loginSuccess()
  8. } else {
  9. loginListener.loginFail(response.errorMsg)
  10. }
  11. }
  12. })
  13. }
  14. }

到此为止,MVP架构就搭建成功了,因为自己本身也是个学习者,所以文章不能起到太大教学作用,目前只能作为记录以及笔记使用,所以文章中有不妥之处欢迎大家评论区指出来,大家共同讨论,共同进步!谢谢大家的支持与阅读!


转载:https://blog.csdn.net/qq_40785165/article/details/113200783
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场