从零开始搭建Android MVP架构

简介

笔者之前接触过一些Android开发,不过对框架了解甚微,本篇文章以笔者的学习角度,描述如何从零开始搭建Android MVP架构,由于笔者的基础有限,还请广大网友多多指教~

开发环境

macOS Mojave v10.14.3
Android Studio v3.3.2
模拟器 API 27
语言 Kotlin v1.3.21

开始

Library

首先新建一个Android Hello World项目
在这里插入图片描述
然后新建一个Android Library,命名为BaseLibrary
BaseLibrary 用来存放常用控件、常用操作的工具类、还有一些基类例如BaseActivity

接着新建另一个Android Library,命名为Provider
Provider存放业务相关的共用属性,例如事件,多模块引用,主要做数据共享。
从零开始搭建Android MVP架构_第1张图片

包结构

base

base:
	common 共用类文件
	data: 数据层
		net 网络请求
		potocol 实体类
	ext: Kotlin拓展
	presenter: 
		view 视图回调
	ui:
		activity
		fragment
		adapter

provider

provider:
	common 共用类文件
	event 事件监听
	router 跨模块路由

app

app:
	common 共用类文件
	ui:
		activity
		fragment

这样包结构就大致完成了,具体那些地方需要修改,根据后期项目具体情况决定

依赖关系

Provider依赖BaseLibrary,app依赖Provider,使用以下代码或者通过Android Studio的设置修改依赖

api project(':baselibrary')

注意这里用api是为了方便其他Module依赖Provider,因为implementation不可传递依赖

api、implementation是compile的升级版,具体好处可在Android Development官网查看

功能试验

本项目使用的一些依赖包分享(不一定在博客中展示)

Kotlin拓展工具 Anko
Android智能下拉刷新框架-SmartRefreshLayout
复杂布局 MultiType
图片框架 Glide
Android实用工具 EasyAndroid

Base类

首先定义BaseView,BasePresenter,BaseActivity,BaseMvpActivity

功能模块

新建一个反馈Module,命名为feedback
并新建一个Activity,命名为ListAcvitity,用于展示列表页,并创建对应Layout

接下来需要通过变量控制该模块是否为Application(是否可单独启动)
首先在gradle.properties文件中新建变量 isfeedbackModule
feedback中的build.gradle中通过变量修改

if (isfeedbackModel.toBoolean()) {
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}

这样只需要通过变量就可以控制module是否可以单独启动
从零开始搭建Android MVP架构_第2张图片

View And Presenter 关系

创建ListPresenter : BasePresenterListView : BaseView
从零开始搭建Android MVP架构_第3张图片
并且使ListActivity继承与BaseMvpActivity

class ListActivity : BaseMvpActivity(), ListView
class ListPresenter : BasePresenter()
interface ListView : BaseView

这样Presenter持有View的回调接口,View调用Presenter,Presenter调用module层获取数据之后,调用View的接口回调数据给页面
我这里回调接口是这么写的


interface ListView : BaseView {

    /**
     * 获取反馈列表页面回调
     * @param feedbackList 反馈列表
     */
    fun onLoadOrRefresh(feedbackList : ArrayList)


    /**
     * 加载更多
     * @param feedbackList 反馈列表
     */
    fun onLoadMore(feedbackList: ArrayList)


}

同时,在BaseView中还存在两个常用方法

  /**
     * 加载更多失败
     */
    fun onLoadMoreFail()


    /**
     * 刷新失败
     */
    fun onRefreshFail()

这样一来,能满足简单的列表刷新与加载更多,同时发生错误也能够使用错误回调进行提示等

Service

新建FeedbackService
Service同样是用接口定义,代码如下

    /**
     * 获取反馈列表
     *
     * @param page 页码
     * @return
     */
    fun getFeedbackList(page : Int) : Observable>

再通过实现类,去调用repository,实现类代码如下

   override fun getFeedbackList(page: Int): Observable> {

        val repository = FeedbackRepository()

        return repository.getFeedbackList(page)

    }

这里提到Repository,代码还没贴上来,之后再说

API

本项目采用Retrofit网络请求框架,具体如何搭建请看本人其他博客
本篇文章只专注项目结构

反馈列表API如下


    /**
     * 获取反馈列表
     * @param page 页码
     * @return 反馈列表
     */
    @GET("api/feedback")
    fun getFeedbackList(@Query("page") page : Int) : Observable>

Repository

Repository 用来作Service与Module的中间层,负责调用网络请求框架获取数据

class FeedbackRepository{

    fun getFeedbackList(page: Int): Observable> {
        return RetrofitFactory.instance.create(FeedbackApi::class.java)
            .getFeedbackList(page)
    }

}

Presenter

这样一来,只需要在Presenter中调用Service的方法,便可请求获取数据,本项目中,采用Rx进行线程管理
加载更多与刷新代码类似,这里只展示加载更多

fun loadMore() {
        currentPage++
        EasyLog.DEFAULT.i("加载第 $currentPage 页 \n 总页数为 $totalPages 页")
        feedbackService.getFeedbackList(currentPage)
            .execute()
            .subscribe(
                {
                    val cursor = it.cursor

                    totalPages = cursor.total_pages

                    mView.onLoadMore(it.data)
                }, {
                    EasyLog.DEFAULT.e(it.message)
                    mView.onLoadMoreFail()
                }
            ).add(mCompositeDisposable)
    }

感谢Rx的灵性,把Json都转成对应实体类了,只需要操作实体类就行了,十分方便

展望

暂时没使用注解方式实现实例化,下一篇博客描述如何使用Retrofit网络请求框架,那下下篇博客就描述如何通过Dagger注解实例化吧

然后对于MVP框架,由于是第一次接触,很多地方可能还有好大的误解,希望大家多多指导

你可能感兴趣的:(Android)