笔者之前接触过一些Android开发,不过对框架了解甚微,本篇文章以笔者的学习角度,描述如何从零开始搭建Android MVP架构,由于笔者的基础有限,还请广大网友多多指教~
macOS Mojave v10.14.3
Android Studio v3.3.2
模拟器 API 27
语言 Kotlin v1.3.21
首先新建一个Android Hello World项目
然后新建一个Android Library,命名为BaseLibrary
BaseLibrary 用来存放常用控件、常用操作的工具类、还有一些基类例如BaseActivity
接着新建另一个Android Library,命名为Provider
Provider存放业务相关的共用属性,例如事件,多模块引用,主要做数据共享。
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
首先定义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'
}
创建ListPresenter : BasePresenter
与ListView : BaseView
并且使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()
这样一来,能满足简单的列表刷新与加载更多,同时发生错误也能够使用错误回调进行提示等
新建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,代码还没贴上来,之后再说
本项目采用Retrofit网络请求框架,具体如何搭建请看本人其他博客
本篇文章只专注项目结构
反馈列表API如下
/**
* 获取反馈列表
* @param page 页码
* @return 反馈列表
*/
@GET("api/feedback")
fun getFeedbackList(@Query("page") page : Int) : Observable>
Repository 用来作Service与Module的中间层,负责调用网络请求框架获取数据
class FeedbackRepository{
fun getFeedbackList(page: Int): Observable> {
return RetrofitFactory.instance.create(FeedbackApi::class.java)
.getFeedbackList(page)
}
}
这样一来,只需要在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框架,由于是第一次接触,很多地方可能还有好大的误解,希望大家多多指导